| @@ -121,6 +121,11 @@ const ( | |||
| //AI center | |||
| AICenterOfCloudBrainOne = "OpenIOne" | |||
| AICenterOfCloudBrainTwo = "OpenITwo" | |||
| AICenterOfChengdu = "OpenIChengdu" | |||
| //ComputeResource | |||
| GPU = "GPU" | |||
| NPU = "NPU" | |||
| ) | |||
| type Cloudbrain struct { | |||
| @@ -191,6 +196,7 @@ type Cloudbrain struct { | |||
| BenchmarkTypeRankLink string `xorm:"-"` | |||
| StartTime timeutil.TimeStamp | |||
| EndTime timeutil.TimeStamp | |||
| Spec *Specification `xorm:"-"` | |||
| } | |||
| func (task *Cloudbrain) ComputeAndSetDuration() { | |||
| @@ -1707,11 +1713,24 @@ func CloudbrainsVersionList(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int, e | |||
| } | |||
| func CreateCloudbrain(cloudbrain *Cloudbrain) (err error) { | |||
| session := x.NewSession() | |||
| defer session.Close() | |||
| err = session.Begin() | |||
| cloudbrain.TrainJobDuration = DURATION_STR_ZERO | |||
| if _, err = x.NoAutoTime().Insert(cloudbrain); err != nil { | |||
| if _, err = session.NoAutoTime().InsertOne(cloudbrain); err != nil { | |||
| session.Rollback() | |||
| return err | |||
| } | |||
| if cloudbrain.Spec != nil { | |||
| if _, err = session.Insert(NewCloudBrainSpec(cloudbrain.ID, *cloudbrain.Spec)); err != nil { | |||
| session.Rollback() | |||
| return err | |||
| } | |||
| } | |||
| session.Commit() | |||
| go IncreaseDatasetUseCount(cloudbrain.Uuid) | |||
| return nil | |||
| } | |||
| @@ -1990,11 +2009,18 @@ func RestartCloudbrain(old *Cloudbrain, new *Cloudbrain) (err error) { | |||
| return err | |||
| } | |||
| if _, err = sess.NoAutoTime().Insert(new); err != nil { | |||
| if _, err = sess.NoAutoTime().InsertOne(new); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| if new.Spec != nil { | |||
| if _, err = sess.Insert(NewCloudBrainSpec(new.ID, *new.Spec)); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| } | |||
| if err = sess.Commit(); err != nil { | |||
| return err | |||
| } | |||
| @@ -2386,7 +2412,57 @@ func GetCloudbrainByIDs(ids []int64) ([]*Cloudbrain, error) { | |||
| Find(&cloudbrains) | |||
| } | |||
| func GetCloudbrainWithDeletedByIDs(ids []int64) ([]*Cloudbrain, error) { | |||
| cloudbrains := make([]*Cloudbrain, 0) | |||
| return cloudbrains, x. | |||
| In("id", ids).Unscoped().Find(&cloudbrains) | |||
| } | |||
| func GetCloudbrainCountByJobName(jobName, jobType string, typeCloudbrain int) (int, error) { | |||
| count, err := x.Where("job_name = ? and job_type= ? and type = ?", jobName, jobType, typeCloudbrain).Count(new(Cloudbrain)) | |||
| return int(count), err | |||
| } | |||
| func LoadSpecs(tasks []*Cloudbrain) error { | |||
| cloudbrainIds := make([]int64, len(tasks)) | |||
| for i, v := range tasks { | |||
| cloudbrainIds[i] = v.ID | |||
| } | |||
| specs := make([]*CloudbrainSpec, 0) | |||
| err := x.In("cloudbrain_id", cloudbrainIds).Find(&specs) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| specMap := make(map[int64]*CloudbrainSpec) | |||
| for _, v := range specs { | |||
| specMap[v.SpecId] = v | |||
| } | |||
| for _, v := range tasks { | |||
| if specMap[v.ID] != nil { | |||
| v.Spec = specMap[v.ID].ConvertToSpecification() | |||
| } | |||
| } | |||
| return nil | |||
| } | |||
| func LoadSpecs4CloudbrainInfo(tasks []*CloudbrainInfo) error { | |||
| cloudbrainIds := make([]int64, len(tasks)) | |||
| for i, v := range tasks { | |||
| cloudbrainIds[i] = v.Cloudbrain.ID | |||
| } | |||
| specs := make([]*CloudbrainSpec, 0) | |||
| err := x.In("cloudbrain_id", cloudbrainIds).Find(&specs) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| specMap := make(map[int64]*CloudbrainSpec) | |||
| for _, v := range specs { | |||
| specMap[v.CloudbrainID] = v | |||
| } | |||
| for _, v := range tasks { | |||
| if specMap[v.Cloudbrain.ID] != nil { | |||
| v.Cloudbrain.Spec = specMap[v.Cloudbrain.ID].ConvertToSpecification() | |||
| } | |||
| } | |||
| return nil | |||
| } | |||
| @@ -0,0 +1,109 @@ | |||
| package models | |||
| import ( | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| ) | |||
| type CloudbrainSpec struct { | |||
| CloudbrainID int64 `xorm:"pk"` | |||
| SpecId int64 `xorm:"index"` | |||
| SourceSpecId string | |||
| AccCardsNum int | |||
| AccCardType string | |||
| CpuCores int | |||
| MemGiB float32 | |||
| GPUMemGiB float32 | |||
| ShareMemGiB float32 | |||
| ComputeResource string | |||
| UnitPrice int | |||
| QueueId int64 | |||
| QueueCode string | |||
| Cluster string | |||
| AiCenterCode string | |||
| AiCenterName string | |||
| IsExclusive bool | |||
| ExclusiveOrg string | |||
| CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
| UpdatedTime timeutil.TimeStamp `xorm:"updated"` | |||
| } | |||
| func (s CloudbrainSpec) ConvertToSpecification() *Specification { | |||
| return &Specification{ | |||
| ID: s.SpecId, | |||
| SourceSpecId: s.SourceSpecId, | |||
| AccCardsNum: s.AccCardsNum, | |||
| AccCardType: s.AccCardType, | |||
| CpuCores: s.CpuCores, | |||
| MemGiB: s.MemGiB, | |||
| GPUMemGiB: s.GPUMemGiB, | |||
| ShareMemGiB: s.ShareMemGiB, | |||
| ComputeResource: s.ComputeResource, | |||
| UnitPrice: s.UnitPrice, | |||
| QueueId: s.QueueId, | |||
| QueueCode: s.QueueCode, | |||
| Cluster: s.Cluster, | |||
| AiCenterCode: s.AiCenterCode, | |||
| AiCenterName: s.AiCenterName, | |||
| IsExclusive: s.IsExclusive, | |||
| ExclusiveOrg: s.ExclusiveOrg, | |||
| } | |||
| } | |||
| func NewCloudBrainSpec(cloudbrainId int64, s Specification) CloudbrainSpec { | |||
| return CloudbrainSpec{ | |||
| CloudbrainID: cloudbrainId, | |||
| SpecId: s.ID, | |||
| SourceSpecId: s.SourceSpecId, | |||
| AccCardsNum: s.AccCardsNum, | |||
| AccCardType: s.AccCardType, | |||
| CpuCores: s.CpuCores, | |||
| MemGiB: s.MemGiB, | |||
| GPUMemGiB: s.GPUMemGiB, | |||
| ShareMemGiB: s.ShareMemGiB, | |||
| ComputeResource: s.ComputeResource, | |||
| UnitPrice: s.UnitPrice, | |||
| QueueId: s.QueueId, | |||
| QueueCode: s.QueueCode, | |||
| Cluster: s.Cluster, | |||
| AiCenterCode: s.AiCenterCode, | |||
| AiCenterName: s.AiCenterName, | |||
| IsExclusive: s.IsExclusive, | |||
| ExclusiveOrg: s.ExclusiveOrg, | |||
| } | |||
| } | |||
| func InsertCloudbrainSpec(c CloudbrainSpec) (int64, error) { | |||
| return x.Insert(&c) | |||
| } | |||
| func GetCloudbrainSpecByID(cloudbrainId int64) (*CloudbrainSpec, error) { | |||
| r := &CloudbrainSpec{} | |||
| if has, err := x.Where("cloudbrain_id = ?", cloudbrainId).Get(r); err != nil { | |||
| return nil, err | |||
| } else if !has { | |||
| return nil, nil | |||
| } | |||
| return r, nil | |||
| } | |||
| func FindCloudbrainTask(page, pageSize int) ([]*Cloudbrain, error) { | |||
| r := make([]*Cloudbrain, 0) | |||
| err := x.Unscoped(). | |||
| Limit(pageSize, (page-1)*pageSize). | |||
| OrderBy("cloudbrain.id"). | |||
| Find(&r) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| return r, nil | |||
| } | |||
| func CountNoSpecHistoricTask() (int64, error) { | |||
| n, err := x.Unscoped(). | |||
| Where(" 1=1 and not exists (select 1 from cloudbrain_spec where cloudbrain.id = cloudbrain_spec.cloudbrain_id)"). | |||
| Count(&Cloudbrain{}) | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| return n, nil | |||
| } | |||
| @@ -131,13 +131,17 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions) | |||
| permission = false | |||
| datasets[i].Repo.GetOwner() | |||
| if !permission { | |||
| isCollaborator, _ := datasets[i].Repo.IsCollaborator(opts.User.ID) | |||
| isInRepoTeam,_:=datasets[i].Repo.IsInRepoTeam(opts.User.ID) | |||
| if isCollaborator ||isInRepoTeam { | |||
| log.Info("Collaborator user may visit the attach.") | |||
| if datasets[i].Repo.OwnerID==opts.User.ID{ | |||
| permission = true | |||
| }else{ | |||
| isCollaborator, _ := datasets[i].Repo.IsCollaborator(opts.User.ID) | |||
| isInRepoTeam,_:=datasets[i].Repo.IsInRepoTeam(opts.User.ID) | |||
| if isCollaborator ||isInRepoTeam { | |||
| permission = true | |||
| } | |||
| } | |||
| } | |||
| permissionMap[datasets[i].ID] = permission | |||
| @@ -150,6 +150,7 @@ func init() { | |||
| new(ResourceScene), | |||
| new(ResourceSceneSpec), | |||
| new(AdminOperateLog), | |||
| new(CloudbrainSpec), | |||
| new(CloudbrainTemp), | |||
| new(DatasetReference), | |||
| ) | |||
| @@ -71,6 +71,8 @@ func (r ResourceQueueReq) ToDTO() ResourceQueue { | |||
| q.AiCenterName = "云脑一" | |||
| } else if r.AiCenterCode == AICenterOfCloudBrainTwo { | |||
| q.AiCenterName = "云脑二" | |||
| } else if r.AiCenterCode == AICenterOfChengdu { | |||
| q.AiCenterName = "启智成都智算" | |||
| } | |||
| } | |||
| return q | |||
| @@ -2,6 +2,7 @@ package models | |||
| import ( | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| "fmt" | |||
| "xorm.io/builder" | |||
| ) | |||
| @@ -22,6 +23,7 @@ type ResourceSpecification struct { | |||
| ShareMemGiB float32 | |||
| UnitPrice int | |||
| Status int | |||
| IsAvailable bool | |||
| IsAutomaticSync bool | |||
| CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
| CreatedBy int64 | |||
| @@ -40,6 +42,7 @@ func (r ResourceSpecification) ConvertToRes() *ResourceSpecificationRes { | |||
| GPUMemGiB: r.GPUMemGiB, | |||
| UnitPrice: r.UnitPrice, | |||
| Status: r.Status, | |||
| IsAvailable: r.IsAvailable, | |||
| UpdatedTime: r.UpdatedTime, | |||
| } | |||
| } | |||
| @@ -72,14 +75,16 @@ func (r ResourceSpecificationReq) ToDTO() ResourceSpecification { | |||
| IsAutomaticSync: r.IsAutomaticSync, | |||
| CreatedBy: r.CreatorId, | |||
| UpdatedBy: r.CreatorId, | |||
| IsAvailable: true, | |||
| } | |||
| } | |||
| type SearchResourceSpecificationOptions struct { | |||
| ListOptions | |||
| QueueId int64 | |||
| Status int | |||
| Cluster string | |||
| QueueId int64 | |||
| Status int | |||
| Cluster string | |||
| AvailableCode int | |||
| } | |||
| type SearchResourceBriefSpecificationOptions struct { | |||
| @@ -113,6 +118,7 @@ type ResourceSpecificationRes struct { | |||
| ShareMemGiB float32 | |||
| UnitPrice int | |||
| Status int | |||
| IsAvailable bool | |||
| UpdatedTime timeutil.TimeStamp | |||
| } | |||
| @@ -141,6 +147,53 @@ func (r ResourceSpecAndQueue) ConvertToRes() *ResourceSpecAndQueueRes { | |||
| } | |||
| } | |||
| type FindSpecsOptions struct { | |||
| JobType JobType | |||
| ComputeResource string | |||
| Cluster string | |||
| AiCenterCode string | |||
| SpecId int64 | |||
| QueueCode string | |||
| SourceSpecId string | |||
| AccCardsNum int | |||
| UseAccCardsNum bool | |||
| AccCardType string | |||
| CpuCores int | |||
| UseCpuCores bool | |||
| MemGiB float32 | |||
| UseMemGiB bool | |||
| GPUMemGiB float32 | |||
| UseGPUMemGiB bool | |||
| ShareMemGiB float32 | |||
| UseShareMemGiB bool | |||
| //if true,find specs no matter used or not used in scene. if false,only find specs used in scene | |||
| RequestAll bool | |||
| } | |||
| type Specification struct { | |||
| ID int64 | |||
| SourceSpecId string | |||
| AccCardsNum int | |||
| AccCardType string | |||
| CpuCores int | |||
| MemGiB float32 | |||
| GPUMemGiB float32 | |||
| ShareMemGiB float32 | |||
| ComputeResource string | |||
| UnitPrice int | |||
| QueueId int64 | |||
| QueueCode string | |||
| Cluster string | |||
| AiCenterCode string | |||
| AiCenterName string | |||
| IsExclusive bool | |||
| ExclusiveOrg string | |||
| } | |||
| func (Specification) TableName() string { | |||
| return "resource_specification" | |||
| } | |||
| func InsertResourceSpecification(r ResourceSpecification) (int64, error) { | |||
| return x.Insert(&r) | |||
| } | |||
| @@ -167,6 +220,11 @@ func SearchResourceSpecification(opts SearchResourceSpecificationOptions) (int64 | |||
| if opts.Cluster != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.cluster": opts.Cluster}) | |||
| } | |||
| if opts.AvailableCode == 1 { | |||
| cond = cond.And(builder.Eq{"resource_specification.is_available": true}) | |||
| } else if opts.AvailableCode == 2 { | |||
| cond = cond.And(builder.Eq{"resource_specification.is_available": false}) | |||
| } | |||
| //cond = cond.And(builder.Or(builder.Eq{"resource_queue.deleted_time": 0}).Or(builder.IsNull{"resource_queue.deleted_time"})) | |||
| n, err := x.Where(cond).Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | |||
| Unscoped().Count(&ResourceSpecAndQueue{}) | |||
| @@ -256,7 +314,7 @@ func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceS | |||
| return err | |||
| } | |||
| if len(deleteIds) > 0 { | |||
| if _, err = sess.In("id", deleteIds).Update(&ResourceSpecification{Status: SpecOffShelf}); err != nil { | |||
| if _, err = sess.Cols("status", "is_available").In("id", deleteIds).Update(&ResourceSpecification{Status: SpecOffShelf, IsAvailable: false}); err != nil { | |||
| return err | |||
| } | |||
| if _, err = sess.In("spec_id", deleteIds).Delete(&ResourceSceneSpec{}); err != nil { | |||
| @@ -267,7 +325,7 @@ func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceS | |||
| //update exists specs | |||
| if len(updateList) > 0 { | |||
| for _, v := range updateList { | |||
| if _, err = sess.ID(v.ID).Update(&v); err != nil { | |||
| if _, err = sess.ID(v.ID).UseBool("is_available").Update(&v); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| @@ -283,3 +341,221 @@ func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceS | |||
| return sess.Commit() | |||
| } | |||
| //FindSpecs | |||
| func FindSpecs(opts FindSpecsOptions) ([]*Specification, error) { | |||
| var cond = builder.NewCond() | |||
| if !opts.RequestAll && opts.JobType != "" { | |||
| cond = cond.And(builder.Eq{"resource_scene.job_type": opts.JobType}) | |||
| } | |||
| if opts.ComputeResource != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.compute_resource": opts.ComputeResource}) | |||
| } | |||
| if opts.Cluster != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.cluster": opts.Cluster}) | |||
| } | |||
| if opts.AiCenterCode != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.ai_center_code": opts.AiCenterCode}) | |||
| } | |||
| if opts.SpecId > 0 { | |||
| cond = cond.And(builder.Eq{"resource_specification.id": opts.SpecId}) | |||
| } | |||
| if opts.QueueCode != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.queue_code": opts.QueueCode}) | |||
| } | |||
| if opts.SourceSpecId != "" { | |||
| cond = cond.And(builder.Eq{"resource_specification.source_spec_id": opts.SourceSpecId}) | |||
| } | |||
| if opts.UseAccCardsNum { | |||
| cond = cond.And(builder.Eq{"resource_specification.acc_cards_num": opts.AccCardsNum}) | |||
| } | |||
| if opts.AccCardType != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.acc_card_type": opts.AccCardType}) | |||
| } | |||
| if opts.UseCpuCores { | |||
| cond = cond.And(builder.Eq{"resource_specification.cpu_cores": opts.CpuCores}) | |||
| } | |||
| if opts.UseMemGiB { | |||
| cond = cond.And(builder.Eq{"resource_specification.mem_gi_b": opts.MemGiB}) | |||
| } | |||
| if opts.UseGPUMemGiB { | |||
| cond = cond.And(builder.Eq{"resource_specification.gpu_mem_gi_b": opts.GPUMemGiB}) | |||
| } | |||
| if opts.UseShareMemGiB { | |||
| cond = cond.And(builder.Eq{"resource_specification.share_mem_gi_b": opts.ShareMemGiB}) | |||
| } | |||
| r := make([]*Specification, 0) | |||
| s := x.Where(cond). | |||
| Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id") | |||
| if !opts.RequestAll { | |||
| s = s.Join("INNER", "resource_scene_spec", "resource_scene_spec.spec_id = resource_specification.id"). | |||
| Join("INNER", "resource_scene", "resource_scene_spec.scene_id = resource_scene.id") | |||
| } | |||
| err := s.OrderBy("resource_queue.compute_resource asc,resource_queue.acc_card_type asc,resource_specification.acc_cards_num asc,resource_specification.cpu_cores asc,resource_specification.mem_gi_b asc,resource_specification.share_mem_gi_b asc"). | |||
| Unscoped().Find(&r) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| return r, nil | |||
| } | |||
| func InitQueueAndSpec(queue ResourceQueue, spec ResourceSpecification) (*Specification, error) { | |||
| sess := x.NewSession() | |||
| defer sess.Close() | |||
| sess.Begin() | |||
| param := ResourceQueue{ | |||
| QueueCode: queue.QueueCode, | |||
| Cluster: queue.Cluster, | |||
| AiCenterCode: queue.AiCenterCode, | |||
| ComputeResource: queue.ComputeResource, | |||
| AccCardType: queue.AccCardType, | |||
| } | |||
| _, err := sess.Get(¶m) | |||
| if err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| if param.ID == 0 { | |||
| _, err = sess.InsertOne(&queue) | |||
| if err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| } else { | |||
| queue = param | |||
| } | |||
| spec.QueueId = queue.ID | |||
| _, err = sess.InsertOne(&spec) | |||
| if err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| sess.Commit() | |||
| return BuildSpecification(queue, spec), nil | |||
| } | |||
| func BuildSpecification(queue ResourceQueue, spec ResourceSpecification) *Specification { | |||
| return &Specification{ | |||
| ID: spec.ID, | |||
| SourceSpecId: spec.SourceSpecId, | |||
| AccCardsNum: spec.AccCardsNum, | |||
| AccCardType: queue.AccCardType, | |||
| CpuCores: spec.CpuCores, | |||
| MemGiB: spec.MemGiB, | |||
| GPUMemGiB: spec.GPUMemGiB, | |||
| ShareMemGiB: spec.ShareMemGiB, | |||
| ComputeResource: queue.ComputeResource, | |||
| UnitPrice: spec.UnitPrice, | |||
| QueueId: queue.ID, | |||
| QueueCode: queue.QueueCode, | |||
| Cluster: queue.Cluster, | |||
| AiCenterCode: queue.AiCenterCode, | |||
| AiCenterName: queue.AiCenterName, | |||
| } | |||
| } | |||
| func GetCloudbrainOneAccCardType(queueCode string) string { | |||
| switch queueCode { | |||
| case "a100": | |||
| return "A100" | |||
| case "openidebug": | |||
| return "T4" | |||
| case "openidgx": | |||
| return "V100" | |||
| } | |||
| return "" | |||
| } | |||
| var cloudbrainTwoSpecsInitFlag = false | |||
| var cloudbrainTwoSpecs map[string]*Specification | |||
| func GetCloudbrainTwoSpecs() (map[string]*Specification, error) { | |||
| if !cloudbrainTwoSpecsInitFlag { | |||
| r, err := InitCloudbrainTwoSpecs() | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| cloudbrainTwoSpecsInitFlag = true | |||
| cloudbrainTwoSpecs = r | |||
| } | |||
| return cloudbrainTwoSpecs, nil | |||
| } | |||
| func InitCloudbrainTwoSpecs() (map[string]*Specification, error) { | |||
| r := make(map[string]*Specification, 0) | |||
| queue, err := GetResourceQueue(&ResourceQueue{QueueCode: "openisupport"}) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if queue == nil { | |||
| queue = &ResourceQueue{ | |||
| QueueCode: "openisupport", | |||
| Cluster: OpenICluster, | |||
| AiCenterCode: AICenterOfCloudBrainTwo, | |||
| AiCenterName: "云脑二", | |||
| ComputeResource: NPU, | |||
| AccCardType: "ASCEND910", | |||
| Remark: "处理历史云脑任务时自动生成", | |||
| } | |||
| _, err = x.InsertOne(queue) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| } | |||
| for i := 1; i <= 8; i = i * 2 { | |||
| sourceSpecId := "modelarts.bm.910.arm.public." + fmt.Sprint(i) | |||
| spec, err := GetResourceSpecification(&ResourceSpecification{ | |||
| SourceSpecId: sourceSpecId, | |||
| QueueId: queue.ID, | |||
| }) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if spec == nil { | |||
| spec = &ResourceSpecification{ | |||
| QueueId: queue.ID, | |||
| SourceSpecId: sourceSpecId, | |||
| AccCardsNum: i, | |||
| CpuCores: i * 24, | |||
| MemGiB: float32(i * 256), | |||
| GPUMemGiB: float32(32), | |||
| Status: SpecOffShelf, | |||
| IsAvailable: true, | |||
| } | |||
| _, err = x.Insert(spec) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| } | |||
| r[sourceSpecId] = BuildSpecification(*queue, *spec) | |||
| } | |||
| return r, nil | |||
| } | |||
| var grampusSpecsInitFlag = false | |||
| var grampusSpecs map[string]*Specification | |||
| func GetGrampusSpecs() (map[string]*Specification, error) { | |||
| if !grampusSpecsInitFlag { | |||
| specMap := make(map[string]*Specification, 0) | |||
| r, err := FindSpecs(FindSpecsOptions{ | |||
| Cluster: C2NetCluster, | |||
| RequestAll: true, | |||
| }) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| for _, spec := range r { | |||
| specMap[spec.SourceSpecId] = spec | |||
| specMap[spec.SourceSpecId+"_"+spec.AiCenterCode] = spec | |||
| } | |||
| grampusSpecsInitFlag = true | |||
| grampusSpecs = specMap | |||
| } | |||
| return grampusSpecs, nil | |||
| } | |||
| @@ -24,6 +24,7 @@ type CreateCloudBrainForm struct { | |||
| Params string `form:"run_para_list"` | |||
| BranchName string `form:"branch_name"` | |||
| DatasetName string `form:"dataset_name"` | |||
| SpecId int64 `form:"spec_id"` | |||
| } | |||
| type CommitImageCloudBrainForm struct { | |||
| @@ -72,6 +73,7 @@ type CreateCloudBrainInferencForm struct { | |||
| CkptName string `form:"ckpt_name" binding:"Required"` | |||
| LabelName string `form:"label_names" binding:"Required"` | |||
| DatasetName string `form:"dataset_name"` | |||
| SpecId int64 `form:"spec_id"` | |||
| } | |||
| func (f *CreateCloudBrainForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
| @@ -11,15 +11,14 @@ type CreateGrampusTrainJobForm struct { | |||
| Attachment string `form:"attachment" binding:"Required"` | |||
| BootFile string `form:"boot_file" binding:"Required"` | |||
| ImageID string `form:"image_id" binding:"Required"` | |||
| FlavorID string `form:"flavor" binding:"Required"` | |||
| Params string `form:"run_para_list" binding:"Required"` | |||
| Description string `form:"description"` | |||
| BranchName string `form:"branch_name" binding:"Required"` | |||
| FlavorName string `form:"flavor_name" binding:"Required"` | |||
| EngineName string `form:"engine_name" binding:"Required"` | |||
| WorkServerNumber int `form:"work_server_number" binding:"Required"` | |||
| Image string `form:"image"` | |||
| DatasetName string `form:"dataset_name"` | |||
| SpecId int64 `form:"spec_id"` | |||
| } | |||
| func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
| @@ -22,6 +22,7 @@ type CreateModelArtsNotebookForm struct { | |||
| Description string `form:"description"` | |||
| Flavor string `form:"flavor" binding:"Required"` | |||
| ImageId string `form:"image_id" binding:"Required"` | |||
| SpecId int64 `form:"spec_id" binding:"Required"` | |||
| } | |||
| func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
| @@ -46,6 +47,7 @@ type CreateModelArtsTrainJobForm struct { | |||
| VersionName string `form:"version_name" binding:"Required"` | |||
| FlavorName string `form:"flaver_names" binding:"Required"` | |||
| EngineName string `form:"engine_names" binding:"Required"` | |||
| SpecId int64 `form:"spec_id" binding:"Required"` | |||
| } | |||
| type CreateModelArtsInferenceJobForm struct { | |||
| @@ -71,6 +73,7 @@ type CreateModelArtsInferenceJobForm struct { | |||
| ModelName string `form:"model_name" binding:"Required"` | |||
| ModelVersion string `form:"model_version" binding:"Required"` | |||
| CkptName string `form:"ckpt_name" binding:"Required"` | |||
| SpecId int64 `form:"spec_id" binding:"Required"` | |||
| } | |||
| func (f *CreateModelArtsTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
| @@ -61,7 +61,6 @@ type GenerateCloudBrainTaskReq struct { | |||
| Snn4ImageNetPath string | |||
| BrainScorePath string | |||
| JobType string | |||
| GpuQueue string | |||
| Description string | |||
| BranchName string | |||
| BootFile string | |||
| @@ -72,13 +71,13 @@ type GenerateCloudBrainTaskReq struct { | |||
| DatasetInfos map[string]models.DatasetInfo | |||
| BenchmarkTypeID int | |||
| BenchmarkChildTypeID int | |||
| ResourceSpecId int | |||
| ResultPath string | |||
| TrainUrl string | |||
| ModelName string | |||
| ModelVersion string | |||
| CkptName string | |||
| LabelName string | |||
| Spec *models.Specification | |||
| } | |||
| func GetCloudbrainDebugCommand() string { | |||
| @@ -227,50 +226,9 @@ func AdminOrImageCreaterRight(ctx *context.Context) { | |||
| } | |||
| func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
| var resourceSpec *models.ResourceSpec | |||
| var versionCount int | |||
| if req.JobType == string(models.JobTypeTrain) { | |||
| versionCount = 1 | |||
| if TrainResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &TrainResourceSpecs) | |||
| } | |||
| for _, spec := range TrainResourceSpecs.ResourceSpec { | |||
| if req.ResourceSpecId == spec.Id { | |||
| resourceSpec = spec | |||
| break | |||
| } | |||
| } | |||
| } else if req.JobType == string(models.JobTypeInference) { | |||
| if InferenceResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.InferenceResourceSpecs), &InferenceResourceSpecs) | |||
| } | |||
| for _, spec := range InferenceResourceSpecs.ResourceSpec { | |||
| if req.ResourceSpecId == spec.Id { | |||
| resourceSpec = spec | |||
| break | |||
| } | |||
| } | |||
| } else { | |||
| if ResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | |||
| } | |||
| for _, spec := range ResourceSpecs.ResourceSpec { | |||
| if req.ResourceSpecId == spec.Id { | |||
| resourceSpec = spec | |||
| break | |||
| } | |||
| } | |||
| } | |||
| //如果没有匹配到spec信息,尝试从专属资源池获取 | |||
| if resourceSpec == nil && SpecialPools != nil { | |||
| resourceSpec = geMatchResourceSpec(req.JobType, req.GpuQueue, req.ResourceSpecId) | |||
| } | |||
| if resourceSpec == nil { | |||
| log.Error("no such resourceSpecId(%d)", req.ResourceSpecId, req.Ctx.Data["MsgID"]) | |||
| return errors.New("no such resourceSpec") | |||
| } | |||
| volumes := []models.Volume{ | |||
| @@ -342,7 +300,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
| jobResult, err := CreateJob(req.JobName, models.CreateJobParams{ | |||
| JobName: req.JobName, | |||
| RetryCount: 1, | |||
| GpuType: req.GpuQueue, | |||
| GpuType: req.Spec.QueueCode, | |||
| Image: req.Image, | |||
| TaskRoles: []models.TaskRole{ | |||
| { | |||
| @@ -350,10 +308,10 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
| TaskNumber: 1, | |||
| MinSucceededTaskCount: 1, | |||
| MinFailedTaskCount: 1, | |||
| CPUNumber: resourceSpec.CpuNum, | |||
| GPUNumber: resourceSpec.GpuNum, | |||
| MemoryMB: resourceSpec.MemMiB, | |||
| ShmMB: resourceSpec.ShareMemMiB, | |||
| CPUNumber: req.Spec.CpuCores, | |||
| GPUNumber: req.Spec.AccCardsNum, | |||
| MemoryMB: int(req.Spec.MemGiB * 1024), | |||
| ShmMB: int(req.Spec.ShareMemGiB * 1024), | |||
| Command: req.Command, | |||
| NeedIBDevice: false, | |||
| IsMainRole: false, | |||
| @@ -384,8 +342,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
| Type: models.TypeCloudBrainOne, | |||
| Uuid: req.Uuids, | |||
| Image: req.Image, | |||
| GpuQueue: req.GpuQueue, | |||
| ResourceSpecId: req.ResourceSpecId, | |||
| GpuQueue: req.Spec.QueueCode, | |||
| ComputeResource: models.GPUResource, | |||
| BenchmarkTypeID: req.BenchmarkTypeID, | |||
| BenchmarkChildTypeID: req.BenchmarkChildTypeID, | |||
| @@ -405,6 +362,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| CommitID: req.CommitID, | |||
| Spec: req.Spec, | |||
| }) | |||
| if err != nil { | |||
| @@ -416,6 +374,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
| log.Error("GetCloudbrainByJobID failed: %v", err.Error()) | |||
| return err | |||
| } | |||
| stringId := strconv.FormatInt(task.ID, 10) | |||
| if IsBenchmarkJob(req.JobType) { | |||
| @@ -447,25 +406,7 @@ func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTy | |||
| func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error { | |||
| jobName := task.JobName | |||
| var resourceSpec *models.ResourceSpec | |||
| if ResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | |||
| } | |||
| for _, spec := range ResourceSpecs.ResourceSpec { | |||
| if task.ResourceSpecId == spec.Id { | |||
| resourceSpec = spec | |||
| } | |||
| } | |||
| //如果没有匹配到spec信息,尝试从专属资源池获取 | |||
| if resourceSpec == nil && SpecialPools != nil { | |||
| resourceSpec = geMatchResourceSpec(task.JobType, task.GpuQueue, task.ResourceSpecId) | |||
| } | |||
| if resourceSpec == nil { | |||
| log.Error("no such resourceSpecId(%d)", task.ResourceSpecId, ctx.Data["MsgID"]) | |||
| return errors.New("no such resourceSpec") | |||
| } | |||
| spec := task.Spec | |||
| var datasetInfos map[string]models.DatasetInfo | |||
| if task.Uuid != "" { | |||
| var err error | |||
| @@ -547,10 +488,10 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||
| TaskNumber: 1, | |||
| MinSucceededTaskCount: 1, | |||
| MinFailedTaskCount: 1, | |||
| CPUNumber: resourceSpec.CpuNum, | |||
| GPUNumber: resourceSpec.GpuNum, | |||
| MemoryMB: resourceSpec.MemMiB, | |||
| ShmMB: resourceSpec.ShareMemMiB, | |||
| CPUNumber: spec.CpuCores, | |||
| GPUNumber: spec.AccCardsNum, | |||
| MemoryMB: int(spec.MemGiB * 1024), | |||
| ShmMB: int(spec.ShareMemGiB * 1024), | |||
| Command: GetCloudbrainDebugCommand(), //Command, | |||
| NeedIBDevice: false, | |||
| IsMainRole: false, | |||
| @@ -588,6 +529,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| BranchName: task.BranchName, | |||
| Spec: spec, | |||
| } | |||
| err = models.RestartCloudbrain(task, newTask) | |||
| @@ -37,11 +37,10 @@ var ( | |||
| ) | |||
| type GenerateTrainJobReq struct { | |||
| JobName string | |||
| Command string | |||
| ResourceSpecId string | |||
| ImageUrl string //与image_id二选一,都有的情况下优先image_url | |||
| ImageId string | |||
| JobName string | |||
| Command string | |||
| ImageUrl string //与image_id二选一,都有的情况下优先image_url | |||
| ImageId string | |||
| DisplayJobName string | |||
| Uuid string | |||
| @@ -58,7 +57,6 @@ type GenerateTrainJobReq struct { | |||
| BranchName string | |||
| PreVersionId int64 | |||
| PreVersionName string | |||
| FlavorName string | |||
| VersionCount int | |||
| EngineName string | |||
| TotalVersionCount int | |||
| @@ -66,6 +64,7 @@ type GenerateTrainJobReq struct { | |||
| ProcessType string | |||
| DatasetName string | |||
| Params string | |||
| Spec *models.Specification | |||
| } | |||
| func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error) { | |||
| @@ -79,7 +78,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| { | |||
| Name: req.JobName, | |||
| Command: req.Command, | |||
| ResourceSpecId: req.ResourceSpecId, | |||
| ResourceSpecId: req.Spec.SourceSpecId, | |||
| ImageId: req.ImageId, | |||
| ImageUrl: req.ImageUrl, | |||
| CenterID: centerID, | |||
| @@ -114,15 +113,14 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| Parameters: req.Params, | |||
| BootFile: req.BootFile, | |||
| DataUrl: req.DataUrl, | |||
| FlavorCode: req.ResourceSpecId, | |||
| Description: req.Description, | |||
| WorkServerNumber: req.WorkServerNumber, | |||
| FlavorName: req.FlavorName, | |||
| EngineName: req.EngineName, | |||
| VersionCount: req.VersionCount, | |||
| TotalVersionCount: req.TotalVersionCount, | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| Spec: req.Spec, | |||
| }) | |||
| if err != nil { | |||
| @@ -84,7 +84,6 @@ type GenerateTrainJobReq struct { | |||
| BootFileUrl string | |||
| DataUrl string | |||
| TrainUrl string | |||
| FlavorCode string | |||
| LogUrl string | |||
| PoolID string | |||
| WorkServerNumber int | |||
| @@ -96,6 +95,7 @@ type GenerateTrainJobReq struct { | |||
| BranchName string | |||
| PreVersionId int64 | |||
| PreVersionName string | |||
| FlavorCode string | |||
| FlavorName string | |||
| VersionCount int | |||
| EngineName string | |||
| @@ -103,6 +103,7 @@ type GenerateTrainJobReq struct { | |||
| UserImageUrl string | |||
| UserCommand string | |||
| DatasetName string | |||
| Spec *models.Specification | |||
| } | |||
| type GenerateInferenceJobReq struct { | |||
| @@ -115,7 +116,6 @@ type GenerateInferenceJobReq struct { | |||
| BootFileUrl string | |||
| DataUrl string | |||
| TrainUrl string | |||
| FlavorCode string | |||
| LogUrl string | |||
| PoolID string | |||
| WorkServerNumber int | |||
| @@ -134,6 +134,7 @@ type GenerateInferenceJobReq struct { | |||
| ModelVersion string | |||
| CkptName string | |||
| ResultUrl string | |||
| Spec *models.Specification | |||
| DatasetName string | |||
| } | |||
| @@ -265,7 +266,7 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin | |||
| return nil | |||
| } | |||
| func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, flavor, imageId string) error { | |||
| func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification) error { | |||
| if poolInfos == nil { | |||
| json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | |||
| } | |||
| @@ -279,7 +280,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc | |||
| jobResult, err := createNotebook2(models.CreateNotebook2Params{ | |||
| JobName: jobName, | |||
| Description: description, | |||
| Flavor: flavor, | |||
| Flavor: spec.SourceSpecId, | |||
| Duration: autoStopDurationMs, | |||
| ImageID: imageId, | |||
| PoolID: poolInfos.PoolInfo[0].PoolId, | |||
| @@ -316,7 +317,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: jobResult.ID, | |||
| JobName: jobName, | |||
| FlavorCode: flavor, | |||
| FlavorCode: spec.SourceSpecId, | |||
| DisplayJobName: displayJobName, | |||
| JobType: string(models.JobTypeDebug), | |||
| Type: models.TypeCloudBrainTwo, | |||
| @@ -326,6 +327,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc | |||
| Description: description, | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| Spec: spec, | |||
| } | |||
| err = models.CreateCloudbrain(task) | |||
| @@ -356,7 +358,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| PoolID: req.PoolID, | |||
| CreateVersion: true, | |||
| Flavor: models.Flavor{ | |||
| Code: req.FlavorCode, | |||
| Code: req.Spec.SourceSpecId, | |||
| }, | |||
| Parameter: req.Parameters, | |||
| UserImageUrl: req.UserImageUrl, | |||
| @@ -378,7 +380,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| PoolID: req.PoolID, | |||
| CreateVersion: true, | |||
| Flavor: models.Flavor{ | |||
| Code: req.FlavorCode, | |||
| Code: req.Spec.SourceSpecId, | |||
| }, | |||
| Parameter: req.Parameters, | |||
| }, | |||
| @@ -427,7 +429,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| BootFile: req.BootFile, | |||
| DataUrl: req.DataUrl, | |||
| LogUrl: req.LogUrl, | |||
| FlavorCode: req.FlavorCode, | |||
| FlavorCode: req.Spec.SourceSpecId, | |||
| Description: req.Description, | |||
| WorkServerNumber: req.WorkServerNumber, | |||
| FlavorName: req.FlavorName, | |||
| @@ -436,6 +438,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| TotalVersionCount: req.TotalVersionCount, | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| Spec: req.Spec, | |||
| }) | |||
| if createErr != nil { | |||
| @@ -487,7 +490,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||
| LogUrl: req.LogUrl, | |||
| PoolID: req.PoolID, | |||
| Flavor: models.Flavor{ | |||
| Code: req.FlavorCode, | |||
| Code: req.Spec.SourceSpecId, | |||
| }, | |||
| Parameter: req.Parameters, | |||
| PreVersionId: req.PreVersionId, | |||
| @@ -508,7 +511,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||
| LogUrl: req.LogUrl, | |||
| PoolID: req.PoolID, | |||
| Flavor: models.Flavor{ | |||
| Code: req.FlavorCode, | |||
| Code: req.Spec.SourceSpecId, | |||
| }, | |||
| Parameter: req.Parameters, | |||
| PreVersionId: req.PreVersionId, | |||
| @@ -575,7 +578,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||
| DataUrl: req.DataUrl, | |||
| LogUrl: req.LogUrl, | |||
| PreVersionId: req.PreVersionId, | |||
| FlavorCode: req.FlavorCode, | |||
| FlavorCode: req.Spec.SourceSpecId, | |||
| Description: req.Description, | |||
| WorkServerNumber: req.WorkServerNumber, | |||
| FlavorName: req.FlavorName, | |||
| @@ -584,6 +587,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||
| VersionCount: VersionListCount + 1, | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| Spec: req.Spec, | |||
| }) | |||
| if createErr != nil { | |||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, createErr.Error()) | |||
| @@ -674,7 +678,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| PoolID: req.PoolID, | |||
| CreateVersion: true, | |||
| Flavor: models.Flavor{ | |||
| Code: req.FlavorCode, | |||
| Code: req.Spec.SourceSpecId, | |||
| }, | |||
| Parameter: req.Parameters, | |||
| }, | |||
| @@ -726,7 +730,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| BootFile: req.BootFile, | |||
| DataUrl: req.DataUrl, | |||
| LogUrl: req.LogUrl, | |||
| FlavorCode: req.FlavorCode, | |||
| FlavorCode: req.Spec.SourceSpecId, | |||
| Description: req.Description, | |||
| WorkServerNumber: req.WorkServerNumber, | |||
| FlavorName: req.FlavorName, | |||
| @@ -742,6 +746,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| ResultUrl: req.ResultUrl, | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| Spec: req.Spec, | |||
| }) | |||
| if err != nil { | |||
| @@ -88,7 +88,7 @@ type Parameters struct { | |||
| } `json:"parameter"` | |||
| } | |||
| func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, flavor, imageId string) error { | |||
| func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification) error { | |||
| imageName, err := GetNotebookImageName(imageId) | |||
| if err != nil { | |||
| log.Error("GetNotebookImageName failed: %v", err.Error()) | |||
| @@ -98,7 +98,7 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr | |||
| jobResult, err := createNotebook(models.CreateNotebookWithoutPoolParams{ | |||
| JobName: jobName, | |||
| Description: description, | |||
| Flavor: flavor, | |||
| Flavor: spec.SourceSpecId, | |||
| Duration: autoStopDurationMs, | |||
| ImageID: imageId, | |||
| Feature: models.NotebookFeature, | |||
| @@ -134,7 +134,7 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr | |||
| RepoID: ctx.Repo.Repository.ID, | |||
| JobID: jobResult.ID, | |||
| JobName: jobName, | |||
| FlavorCode: flavor, | |||
| FlavorCode: spec.SourceSpecId, | |||
| DisplayJobName: displayJobName, | |||
| JobType: string(models.JobTypeDebug), | |||
| Type: models.TypeCDCenter, | |||
| @@ -144,6 +144,7 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr | |||
| Description: description, | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| Spec: spec, | |||
| } | |||
| err = models.CreateCloudbrain(task) | |||
| @@ -3207,6 +3207,9 @@ gpu_num = GPU | |||
| cpu_num = CPU | |||
| memory = Memory | |||
| shared_memory = Shared Memory | |||
| gpu_memory = GPU Memory | |||
| free = Free | |||
| point_hr = Point/hr | |||
| DEBUG = DEBUG | |||
| @@ -3226,6 +3226,9 @@ gpu_num = GPU数 | |||
| cpu_num = CPU数 | |||
| memory = 内存 | |||
| shared_memory = 共享内存 | |||
| gpu_memory = 显存 | |||
| free = 免费 | |||
| point_hr = 积分/时 | |||
| DEBUG = 调试任务 | |||
| SNN4IMAGENET = 评测任务 | |||
| @@ -92,13 +92,13 @@ func CloudBrains(ctx *context.Context) { | |||
| return | |||
| } | |||
| models.LoadSpecs4CloudbrainInfo(ciTasks) | |||
| for i, task := range ciTasks { | |||
| ciTasks[i].CanDebug = true | |||
| ciTasks[i].CanDel = true | |||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | |||
| ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) | |||
| _, cardType, _ := repo.GetCloudbrainCardNumAndType(task.Cloudbrain) | |||
| ciTasks[i].Cloudbrain.CardType = cardType | |||
| ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) | |||
| } | |||
| @@ -8,6 +8,8 @@ import ( | |||
| "code.gitea.io/gitea/routers/response" | |||
| "code.gitea.io/gitea/services/cloudbrain/resource" | |||
| "net/http" | |||
| "strconv" | |||
| "strings" | |||
| ) | |||
| const ( | |||
| @@ -118,11 +120,13 @@ func GetResourceSpecificationList(ctx *context.Context) { | |||
| queue := ctx.QueryInt64("queue") | |||
| status := ctx.QueryInt("status") | |||
| cluster := ctx.Query("cluster") | |||
| available := ctx.QueryInt("available") | |||
| list, err := resource.GetResourceSpecificationList(models.SearchResourceSpecificationOptions{ | |||
| ListOptions: models.ListOptions{Page: page, PageSize: 10}, | |||
| QueueId: queue, | |||
| Status: status, | |||
| Cluster: cluster, | |||
| ListOptions: models.ListOptions{Page: page, PageSize: 10}, | |||
| QueueId: queue, | |||
| Status: status, | |||
| Cluster: cluster, | |||
| AvailableCode: available, | |||
| }) | |||
| if err != nil { | |||
| log.Error("GetResourceSpecificationList error.%v", err) | |||
| @@ -246,3 +250,37 @@ func UpdateResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||
| } | |||
| ctx.JSON(http.StatusOK, response.Success()) | |||
| } | |||
| func RefreshHistorySpec(ctx *context.Context) { | |||
| scope := ctx.Query("scope") | |||
| list := ctx.Query("list") | |||
| var scopeAll = false | |||
| if scope == "all" { | |||
| scopeAll = true | |||
| } | |||
| var ids = make([]int64, 0) | |||
| if list != "" { | |||
| strs := strings.Split(list, "|") | |||
| for _, s := range strs { | |||
| i, err := strconv.ParseInt(s, 10, 64) | |||
| if err != nil { | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| return | |||
| } | |||
| ids = append(ids, i) | |||
| } | |||
| } | |||
| total, success, err := resource.RefreshHistorySpec(scopeAll, ids) | |||
| if err != nil { | |||
| log.Error("RefreshHistorySpec error. %v", err) | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| return | |||
| } | |||
| r := make(map[string]interface{}, 0) | |||
| r["success"] = success | |||
| r["total"] = total | |||
| ctx.JSON(http.StatusOK, response.SuccessWithData(r)) | |||
| } | |||
| @@ -6,6 +6,7 @@ | |||
| package private | |||
| import ( | |||
| "code.gitea.io/gitea/routers/admin" | |||
| "strings" | |||
| "code.gitea.io/gitea/routers/repo" | |||
| @@ -51,6 +52,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/tool/org_stat", OrgStatisticManually) | |||
| m.Post("/tool/update_repo_visit/:date", UpdateRepoVisit) | |||
| m.Post("/task/history_handle/duration", repo.HandleTaskWithNoDuration) | |||
| m.Post("/resources/specification/handle_historical_task", admin.RefreshHistorySpec) | |||
| }, CheckInternalToken) | |||
| } | |||
| @@ -2,6 +2,7 @@ package repo | |||
| import ( | |||
| "bufio" | |||
| "code.gitea.io/gitea/services/cloudbrain/resource" | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| @@ -121,86 +122,7 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
| ctx.Data["QueuesDetail"] = queuesDetail | |||
| } | |||
| cloudbrain.InitSpecialPool() | |||
| if gpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | |||
| } | |||
| ctx.Data["gpu_types"] = gpuInfos.GpuInfo | |||
| if trainGpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||
| } | |||
| ctx.Data["train_gpu_types"] = trainGpuInfos.GpuInfo | |||
| if inferenceGpuInfos == nil && setting.InferenceGpuTypes != "" { | |||
| json.Unmarshal([]byte(setting.InferenceGpuTypes), &inferenceGpuInfos) | |||
| } | |||
| if inferenceGpuInfos != nil { | |||
| ctx.Data["inference_gpu_types"] = inferenceGpuInfos.GpuInfo | |||
| } | |||
| if benchmarkGpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | |||
| } | |||
| ctx.Data["benchmark_gpu_types"] = benchmarkGpuInfos.GpuInfo | |||
| if benchmarkResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.BenchmarkResourceSpecs), &benchmarkResourceSpecs) | |||
| } | |||
| ctx.Data["benchmark_resource_specs"] = benchmarkResourceSpecs.ResourceSpec | |||
| if cloudbrain.ResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||
| } | |||
| ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | |||
| if cloudbrain.TrainResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||
| } | |||
| ctx.Data["train_resource_specs"] = cloudbrain.TrainResourceSpecs.ResourceSpec | |||
| if cloudbrain.InferenceResourceSpecs == nil && setting.InferenceResourceSpecs != "" { | |||
| json.Unmarshal([]byte(setting.InferenceResourceSpecs), &cloudbrain.InferenceResourceSpecs) | |||
| } | |||
| if cloudbrain.InferenceResourceSpecs != nil { | |||
| ctx.Data["inference_resource_specs"] = cloudbrain.InferenceResourceSpecs.ResourceSpec | |||
| } | |||
| if cloudbrain.SpecialPools != nil { | |||
| var debugGpuTypes []*models.GpuInfo | |||
| var trainGpuTypes []*models.GpuInfo | |||
| for _, pool := range cloudbrain.SpecialPools.Pools { | |||
| isOrgMember, _ := models.IsOrganizationMemberByOrgName(pool.Org, ctx.User.ID) | |||
| if isOrgMember { | |||
| for _, jobType := range pool.JobType { | |||
| if jobType == string(models.JobTypeDebug) { | |||
| debugGpuTypes = append(debugGpuTypes, pool.Pool...) | |||
| if pool.ResourceSpec != nil { | |||
| ctx.Data["resource_specs"] = pool.ResourceSpec | |||
| } | |||
| } else if jobType == string(models.JobTypeTrain) { | |||
| trainGpuTypes = append(trainGpuTypes, pool.Pool...) | |||
| if pool.ResourceSpec != nil { | |||
| ctx.Data["train_resource_specs"] = pool.ResourceSpec | |||
| } | |||
| } | |||
| } | |||
| break | |||
| } | |||
| } | |||
| if len(debugGpuTypes) > 0 { | |||
| ctx.Data["gpu_types"] = debugGpuTypes | |||
| } | |||
| if len(trainGpuTypes) > 0 { | |||
| ctx.Data["train_gpu_types"] = trainGpuTypes | |||
| } | |||
| } | |||
| prepareCloudbrainOneSpecs(ctx) | |||
| ctx.Data["params"] = "" | |||
| ctx.Data["branchName"] = ctx.Repo.BranchName | |||
| @@ -218,6 +140,40 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
| return nil | |||
| } | |||
| func prepareCloudbrainOneSpecs(ctx *context.Context) { | |||
| debugSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeDebug, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne, | |||
| }) | |||
| ctx.Data["debug_specs"] = debugSpecs | |||
| trainSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeTrain, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne, | |||
| }) | |||
| ctx.Data["train_specs"] = trainSpecs | |||
| inferenceSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeInference, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne, | |||
| }) | |||
| ctx.Data["inference_specs"] = inferenceSpecs | |||
| benchmarkSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeBenchmark, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne, | |||
| }) | |||
| ctx.Data["benchmark_specs"] = benchmarkSpecs | |||
| } | |||
| func CloudBrainNew(ctx *context.Context) { | |||
| err := cloudBrainNewDataPrepare(ctx) | |||
| if err != nil { | |||
| @@ -235,9 +191,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| image := strings.TrimSpace(form.Image) | |||
| uuids := form.Attachment | |||
| jobType := form.JobType | |||
| gpuQueue := form.GpuType | |||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
| resourceSpecId := form.ResourceSpecId | |||
| branchName := form.BranchName | |||
| bootFile := strings.TrimSpace(form.BootFile) | |||
| repo := ctx.Repo.Repository | |||
| @@ -325,18 +279,10 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| command = commandTrain | |||
| } | |||
| errStr := checkCloudBrainSpecialPool(ctx, jobType, gpuQueue, resourceSpecId) | |||
| if errStr != "" { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(errStr, tpl, &form) | |||
| return | |||
| } | |||
| if branchName == "" { | |||
| branchName = cloudbrain.DefaultBranchName | |||
| } | |||
| errStr = loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ModelMountPath) | |||
| errStr := loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ModelMountPath) | |||
| if errStr != "" { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(ctx.Tr(errStr), tpl, &form) | |||
| @@ -345,6 +291,17 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName) | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobType(jobType), | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne}) | |||
| if err != nil || spec == nil { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("Resource specification not available", tpl, &form) | |||
| return | |||
| } | |||
| req := cloudbrain.GenerateCloudBrainTaskReq{ | |||
| Ctx: ctx, | |||
| DisplayJobName: displayJobName, | |||
| @@ -360,7 +317,6 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
| BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | |||
| JobType: jobType, | |||
| GpuQueue: gpuQueue, | |||
| Description: form.Description, | |||
| BranchName: branchName, | |||
| BootFile: form.BootFile, | |||
| @@ -368,8 +324,8 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| CommitID: commitID, | |||
| BenchmarkTypeID: 0, | |||
| BenchmarkChildTypeID: 0, | |||
| ResourceSpecId: resourceSpecId, | |||
| ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
| Spec: spec, | |||
| } | |||
| err = cloudbrain.GenerateTask(req) | |||
| @@ -417,9 +373,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||
| image := strings.TrimSpace(form.Image) | |||
| uuid := form.Attachment | |||
| jobType := string(models.JobTypeInference) | |||
| gpuQueue := form.GpuType | |||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
| resourceSpecId := form.ResourceSpecId | |||
| branchName := form.BranchName | |||
| bootFile := strings.TrimSpace(form.BootFile) | |||
| labelName := form.LabelName | |||
| @@ -501,7 +455,16 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||
| ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) | |||
| return | |||
| } | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeInference, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne}) | |||
| if err != nil || spec == nil { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("Resource specification not available", tpl, &form) | |||
| return | |||
| } | |||
| req := cloudbrain.GenerateCloudBrainTaskReq{ | |||
| Ctx: ctx, | |||
| DisplayJobName: displayJobName, | |||
| @@ -517,19 +480,18 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||
| Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
| BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | |||
| JobType: jobType, | |||
| GpuQueue: gpuQueue, | |||
| Description: form.Description, | |||
| BranchName: branchName, | |||
| BootFile: form.BootFile, | |||
| Params: form.Params, | |||
| CommitID: commitID, | |||
| ResourceSpecId: resourceSpecId, | |||
| ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
| ModelName: form.ModelName, | |||
| ModelVersion: form.ModelVersion, | |||
| CkptName: form.CkptName, | |||
| TrainUrl: form.TrainUrl, | |||
| LabelName: labelName, | |||
| Spec: spec, | |||
| } | |||
| err = cloudbrain.GenerateTask(req) | |||
| @@ -607,34 +569,25 @@ func CloudBrainRestart(ctx *context.Context) { | |||
| break | |||
| } | |||
| var hasSameResource bool | |||
| if gpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | |||
| } | |||
| for _, resourceType := range gpuInfos.GpuInfo { | |||
| if resourceType.Queue == task.GpuQueue { | |||
| hasSameResource = true | |||
| break | |||
| } | |||
| } | |||
| if !hasSameResource && cloudbrain.SpecialPools != nil { | |||
| for _, specialPool := range cloudbrain.SpecialPools.Pools { | |||
| cloudbrain.IsElementExist(specialPool.JobType, string(models.JobTypeDebug)) | |||
| for _, pool := range specialPool.Pool { | |||
| if pool.Queue == task.GpuQueue { | |||
| hasSameResource = true | |||
| } | |||
| } | |||
| } | |||
| specOld, err := resource.GetCloudbrainSpec(task.ID) | |||
| if err != nil || specOld == nil { | |||
| log.Error("CloudBrainRestart GetCloudbrainSpec error.task.id = %d", task.ID) | |||
| resultCode = "-1" | |||
| errorMsg = "Resource specification not support any more" | |||
| break | |||
| } | |||
| if !hasSameResource { | |||
| log.Error("has no same resource, can not restart", ctx.Data["MsgID"]) | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, specOld.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobType(task.JobType), | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne}) | |||
| if err != nil || spec == nil { | |||
| log.Error("CloudBrainRestart GetAndCheckSpec error.task.id = %d", task.ID) | |||
| resultCode = "-1" | |||
| errorMsg = "the job's version is too old and can not be restarted" | |||
| errorMsg = "Resource specification not support any more" | |||
| break | |||
| } | |||
| task.Spec = spec | |||
| count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, string(models.JobTypeDebug)) | |||
| if err != nil { | |||
| @@ -707,128 +660,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| return | |||
| } | |||
| hasSpec := false | |||
| if task.JobType == string(models.JobTypeTrain) { | |||
| if cloudbrain.TrainResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.TrainResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| ctx.Data["GpuNum"] = tmp.GpuNum | |||
| ctx.Data["CpuNum"] = tmp.CpuNum | |||
| ctx.Data["MemMiB"] = tmp.MemMiB | |||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } else if task.JobType == string(models.JobTypeInference) { | |||
| if cloudbrain.InferenceResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.InferenceResourceSpecs), &cloudbrain.InferenceResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.InferenceResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| ctx.Data["GpuNum"] = tmp.GpuNum | |||
| ctx.Data["CpuNum"] = tmp.CpuNum | |||
| ctx.Data["MemMiB"] = tmp.MemMiB | |||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } else { | |||
| if cloudbrain.ResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| ctx.Data["GpuNum"] = tmp.GpuNum | |||
| ctx.Data["CpuNum"] = tmp.CpuNum | |||
| ctx.Data["MemMiB"] = tmp.MemMiB | |||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } | |||
| if !hasSpec && cloudbrain.SpecialPools != nil { | |||
| for _, specialPool := range cloudbrain.SpecialPools.Pools { | |||
| if specialPool.ResourceSpec != nil { | |||
| for _, spec := range specialPool.ResourceSpec { | |||
| if task.ResourceSpecId == spec.Id { | |||
| ctx.Data["GpuNum"] = spec.GpuNum | |||
| ctx.Data["CpuNum"] = spec.CpuNum | |||
| ctx.Data["MemMiB"] = spec.MemMiB | |||
| ctx.Data["ShareMemMiB"] = spec.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } | |||
| } | |||
| prepareSpec4Show(ctx, task) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| if result != nil { | |||
| jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | |||
| jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | |||
| spec := "GPU数:" + strconv.Itoa(jobRes.Resource.NvidiaComGpu) + ",CPU数:" + strconv.Itoa(jobRes.Resource.CPU) + ",内存(MB):" + jobRes.Resource.Memory | |||
| ctx.Data["resource_spec"] = spec | |||
| if task.JobType == string(models.JobTypeTrain) { | |||
| if trainGpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||
| } | |||
| for _, resourceType := range trainGpuInfos.GpuInfo { | |||
| if resourceType.Queue == jobRes.Config.GpuType { | |||
| ctx.Data["resource_type"] = resourceType.Value | |||
| } | |||
| } | |||
| } else if task.JobType == string(models.JobTypeInference) { | |||
| if inferenceGpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.InferenceGpuTypes), &inferenceGpuInfos) | |||
| } | |||
| for _, resourceType := range inferenceGpuInfos.GpuInfo { | |||
| if resourceType.Queue == jobRes.Config.GpuType { | |||
| ctx.Data["resource_type"] = resourceType.Value | |||
| } | |||
| } | |||
| } else if cloudbrain.IsBenchmarkJob(task.JobType) { | |||
| if benchmarkGpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | |||
| } | |||
| for _, resourceType := range benchmarkGpuInfos.GpuInfo { | |||
| if resourceType.Queue == jobRes.Config.GpuType { | |||
| ctx.Data["resource_type"] = resourceType.Value | |||
| } | |||
| } | |||
| } else { | |||
| if gpuInfos == nil { | |||
| json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | |||
| } | |||
| for _, resourceType := range gpuInfos.GpuInfo { | |||
| if resourceType.Queue == jobRes.Config.GpuType { | |||
| ctx.Data["resource_type"] = resourceType.Value | |||
| } | |||
| } | |||
| } | |||
| if cloudbrain.SpecialPools != nil { | |||
| for _, specialPool := range cloudbrain.SpecialPools.Pools { | |||
| for _, resourceType := range specialPool.Pool { | |||
| if resourceType.Queue == jobRes.Config.GpuType { | |||
| ctx.Data["resource_type"] = resourceType.Value | |||
| } | |||
| } | |||
| } | |||
| } | |||
| taskRoles := jobRes.TaskRoles | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| ctx.Data["taskRes"] = taskRes | |||
| @@ -952,6 +790,85 @@ func CloudBrainDebug(ctx *context.Context) { | |||
| ctx.Redirect(debugUrl) | |||
| } | |||
| func prepareSpec4Show(ctx *context.Context, task *models.Cloudbrain) { | |||
| s, err := resource.GetCloudbrainSpec(task.ID) | |||
| if err != nil { | |||
| log.Info("error:" + err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| return | |||
| } | |||
| ctx.Data["Spec"] = s | |||
| } | |||
| func oldPrepareSpec4Show(ctx *context.Context, task *models.Cloudbrain) { | |||
| hasSpec := false | |||
| if task.JobType == string(models.JobTypeTrain) { | |||
| if cloudbrain.TrainResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.TrainResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| ctx.Data["GpuNum"] = tmp.GpuNum | |||
| ctx.Data["CpuNum"] = tmp.CpuNum | |||
| ctx.Data["MemMiB"] = tmp.MemMiB | |||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } else if task.JobType == string(models.JobTypeInference) { | |||
| if cloudbrain.InferenceResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.InferenceResourceSpecs), &cloudbrain.InferenceResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.InferenceResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| ctx.Data["GpuNum"] = tmp.GpuNum | |||
| ctx.Data["CpuNum"] = tmp.CpuNum | |||
| ctx.Data["MemMiB"] = tmp.MemMiB | |||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } else { | |||
| if cloudbrain.ResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| ctx.Data["GpuNum"] = tmp.GpuNum | |||
| ctx.Data["CpuNum"] = tmp.CpuNum | |||
| ctx.Data["MemMiB"] = tmp.MemMiB | |||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } | |||
| if !hasSpec && cloudbrain.SpecialPools != nil { | |||
| for _, specialPool := range cloudbrain.SpecialPools.Pools { | |||
| if specialPool.ResourceSpec != nil { | |||
| for _, spec := range specialPool.ResourceSpec { | |||
| if task.ResourceSpecId == spec.Id { | |||
| ctx.Data["GpuNum"] = spec.GpuNum | |||
| ctx.Data["CpuNum"] = spec.CpuNum | |||
| ctx.Data["MemMiB"] = spec.MemMiB | |||
| ctx.Data["ShareMemMiB"] = spec.ShareMemMiB | |||
| break | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| func CloudBrainCommitImageShow(ctx *context.Context) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| ctx.Data["Type"] = ctx.Cloudbrain.Type | |||
| @@ -2285,10 +2202,8 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| image := strings.TrimSpace(form.Image) | |||
| gpuQueue := form.GpuType | |||
| command := cloudbrain.CommandBenchmark | |||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
| resourceSpecId := cloudbrain.BenchMarkResourceID | |||
| benchmarkTypeID := form.BenchmarkTypeID | |||
| benchmarkChildTypeID := form.BenchmarkChildTypeID | |||
| @@ -2329,19 +2244,14 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||
| return | |||
| } | |||
| _, err = getBenchmarkGpuQueue(gpuQueue) | |||
| if err != nil { | |||
| log.Error("getBenchmarkGpuQueue failed:%v", err, ctx.Data["MsgID"]) | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeBenchmark, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne}) | |||
| if err != nil || spec == nil { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("gpu queue error", tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } | |||
| _, err = getBenchmarkResourceSpec(resourceSpecId) | |||
| if err != nil { | |||
| log.Error("getBenchmarkResourceSpec failed:%v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("resource spec error", tplCloudBrainBenchmarkNew, &form) | |||
| ctx.RenderWithErr("Resource specification not available", tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } | |||
| @@ -2402,14 +2312,8 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||
| } | |||
| benchmarkPath := setting.JobPath + jobName + cloudbrain.BenchMarkMountPath | |||
| var gpuType string | |||
| for _, gpuInfo := range gpuInfos.GpuInfo { | |||
| if gpuInfo.Queue == gpuQueue { | |||
| gpuType = gpuInfo.Value | |||
| } | |||
| } | |||
| if err := downloadRateCode(repo, jobName, childInfo.Owner, childInfo.RepoName, benchmarkPath, form.BenchmarkCategory, gpuType, ctx.User.Name); err != nil { | |||
| if err := downloadRateCode(repo, jobName, childInfo.Owner, childInfo.RepoName, benchmarkPath, form.BenchmarkCategory, spec.AccCardType, ctx.User.Name); err != nil { | |||
| log.Error("downloadRateCode failed, %v", err, ctx.Data["MsgID"]) | |||
| //cloudBrainNewDataPrepare(ctx) | |||
| //ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | |||
| @@ -2448,7 +2352,6 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||
| Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
| BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | |||
| JobType: string(models.JobTypeBenchmark), | |||
| GpuQueue: gpuQueue, | |||
| Description: form.Description, | |||
| BranchName: cloudbrain.DefaultBranchName, | |||
| BootFile: "", | |||
| @@ -2456,8 +2359,8 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||
| CommitID: "", | |||
| BenchmarkTypeID: benchmarkTypeID, | |||
| BenchmarkChildTypeID: benchmarkChildTypeID, | |||
| ResourceSpecId: resourceSpecId, | |||
| ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
| Spec: spec, | |||
| } | |||
| err = cloudbrain.GenerateTask(req) | |||
| @@ -2477,9 +2380,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||
| image := form.Image | |||
| uuid := form.Attachment | |||
| jobType := form.JobType | |||
| gpuQueue := form.GpuType | |||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
| resourceSpecId := form.ResourceSpecId | |||
| branchName := cloudbrain.DefaultBranchName | |||
| repo := ctx.Repo.Repository | |||
| @@ -2561,6 +2462,16 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||
| ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) | |||
| return | |||
| } | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeBenchmark, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne}) | |||
| if err != nil || spec == nil { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("Resource specification not available", tpl, &form) | |||
| return | |||
| } | |||
| log.Info("Command=" + command) | |||
| log.Info("ModelPath=" + storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/")) | |||
| req := cloudbrain.GenerateCloudBrainTaskReq{ | |||
| @@ -2578,7 +2489,6 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||
| Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
| BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | |||
| JobType: jobType, | |||
| GpuQueue: gpuQueue, | |||
| Description: form.Description, | |||
| BranchName: branchName, | |||
| BootFile: form.BootFile, | |||
| @@ -2586,8 +2496,8 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||
| CommitID: "", | |||
| BenchmarkTypeID: 0, | |||
| BenchmarkChildTypeID: benchmarkChildTypeID, | |||
| ResourceSpecId: resourceSpecId, | |||
| ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
| Spec: spec, | |||
| } | |||
| err = cloudbrain.GenerateTask(req) | |||
| @@ -1,6 +1,7 @@ | |||
| package repo | |||
| import ( | |||
| "code.gitea.io/gitea/services/cloudbrain/resource" | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| @@ -106,15 +107,11 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err | |||
| } | |||
| } | |||
| //get valid resource specs | |||
| specs, err := grampus.GetResourceSpecs(processType) | |||
| grampusSpecs := getFilterSpecBySpecialPool(specs, includeCenters, excludeCenters) | |||
| if err != nil { | |||
| log.Error("GetResourceSpecs failed:", err.Error()) | |||
| } else { | |||
| ctx.Data["flavor_infos"] = grampusSpecs | |||
| //prepare available specs | |||
| if processType == grampus.ProcessorTypeNPU { | |||
| prepareGrampusTrainSpecs(ctx, models.NPU) | |||
| } else if processType == grampus.ProcessorTypeGPU { | |||
| prepareGrampusTrainSpecs(ctx, models.GPU) | |||
| } | |||
| //get branches | |||
| @@ -140,6 +137,15 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err | |||
| return nil | |||
| } | |||
| func prepareGrampusTrainSpecs(ctx *context.Context, computeResource string) { | |||
| noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeTrain, | |||
| ComputeResource: computeResource, | |||
| Cluster: models.C2NetCluster, | |||
| }) | |||
| ctx.Data["Specs"] = noteBookSpecs | |||
| } | |||
| func getFilterSpecBySpecialPool(specs *models.GetGrampusResourceSpecsResult, includeCenters map[string]struct{}, excludeCenters map[string]struct{}) []models.GrampusSpec { | |||
| if len(includeCenters) == 0 && len(excludeCenters) == 0 { | |||
| return specs.Infos | |||
| @@ -206,7 +212,6 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| codeMinioPath := setting.CBCodePathPrefix + jobName + cloudbrain.CodeMountPath + "/" | |||
| dataMinioPath := setting.Attachment.Minio.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid | |||
| branchName := form.BranchName | |||
| flavorName := form.FlavorName | |||
| image := strings.TrimSpace(form.Image) | |||
| if !jobNamePattern.MatchString(displayJobName) { | |||
| @@ -272,6 +277,18 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| } | |||
| } | |||
| //check specification | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeTrain, | |||
| ComputeResource: models.GPU, | |||
| Cluster: models.C2NetCluster, | |||
| }) | |||
| if err != nil || spec == nil { | |||
| grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) | |||
| ctx.RenderWithErr("Resource specification not available", tplGrampusTrainJobGPUNew, &form) | |||
| return | |||
| } | |||
| //check dataset | |||
| attachment, err := models.GetAttachmentByUUID(uuid) | |||
| if err != nil { | |||
| @@ -336,7 +353,6 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| ComputeResource: models.GPUResource, | |||
| ProcessType: grampus.ProcessorTypeGPU, | |||
| Command: command, | |||
| ResourceSpecId: form.FlavorID, | |||
| ImageUrl: image, | |||
| Description: description, | |||
| BootFile: bootFile, | |||
| @@ -344,12 +360,12 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| CommitID: commitID, | |||
| BranchName: branchName, | |||
| Params: form.Params, | |||
| FlavorName: flavorName, | |||
| EngineName: image, | |||
| DatasetName: attachment.Name, | |||
| IsLatestVersion: modelarts.IsLatestVersion, | |||
| VersionCount: modelarts.VersionCountOne, | |||
| WorkServerNumber: 1, | |||
| Spec: spec, | |||
| } | |||
| err = grampus.GenerateTrainJob(ctx, req) | |||
| @@ -397,7 +413,6 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| dataObsPath := setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/" | |||
| branchName := form.BranchName | |||
| isLatestVersion := modelarts.IsLatestVersion | |||
| flavorName := form.FlavorName | |||
| versionCount := modelarts.VersionCountOne | |||
| engineName := form.EngineName | |||
| @@ -464,6 +479,18 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| } | |||
| } | |||
| //check specification | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeTrain, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.C2NetCluster, | |||
| }) | |||
| if err != nil || spec == nil { | |||
| grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) | |||
| ctx.RenderWithErr("Resource specification not available", tplGrampusTrainJobNPUNew, &form) | |||
| return | |||
| } | |||
| //check dataset | |||
| attachment, err := models.GetAttachmentByUUID(uuid) | |||
| if err != nil { | |||
| @@ -518,7 +545,6 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| ComputeResource: models.NPUResource, | |||
| ProcessType: grampus.ProcessorTypeNPU, | |||
| Command: command, | |||
| ResourceSpecId: form.FlavorID, | |||
| ImageId: form.ImageID, | |||
| DataUrl: dataObsPath, | |||
| Description: description, | |||
| @@ -531,11 +557,11 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| IsLatestVersion: isLatestVersion, | |||
| BranchName: branchName, | |||
| Params: form.Params, | |||
| FlavorName: flavorName, | |||
| EngineName: engineName, | |||
| VersionCount: versionCount, | |||
| TotalVersionCount: modelarts.TotalVersionCount, | |||
| DatasetName: attachment.Name, | |||
| Spec: spec, | |||
| } | |||
| err = grampus.GenerateTrainJob(ctx, req) | |||
| @@ -712,6 +738,7 @@ func GrampusTrainJobShow(ctx *context.Context) { | |||
| taskList := make([]*models.Cloudbrain, 0) | |||
| taskList = append(taskList, task) | |||
| prepareSpec4Show(ctx, task) | |||
| ctx.Data["version_list_task"] = taskList | |||
| ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false) | |||
| ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | |||
| @@ -3,6 +3,7 @@ package repo | |||
| import ( | |||
| "archive/zip" | |||
| "code.gitea.io/gitea/modules/modelarts_cd" | |||
| "code.gitea.io/gitea/services/cloudbrain/resource" | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| @@ -130,8 +131,8 @@ func notebookNewDataPrepare(ctx *context.Context) error { | |||
| } | |||
| ctx.Data["attachments"] = attachs | |||
| ctx.Data["images"] = setting.StImageInfos.ImageInfo | |||
| ctx.Data["flavors"] = setting.StFlavorInfo.FlavorInfo | |||
| setSpecBySpecialPoolConfig(ctx, string(models.JobTypeDebug)) | |||
| prepareCloudbrainTwoDebugSpecs(ctx) | |||
| ctx.Data["datasetType"] = models.TypeCloudBrainTwo | |||
| @@ -141,13 +142,70 @@ func notebookNewDataPrepare(ctx *context.Context) error { | |||
| return nil | |||
| } | |||
| func prepareCloudbrainTwoDebugSpecs(ctx *context.Context) { | |||
| aiCenterCode := models.AICenterOfCloudBrainTwo | |||
| if setting.ModelartsCD.Enabled { | |||
| aiCenterCode = models.AICenterOfChengdu | |||
| } | |||
| noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeDebug, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: aiCenterCode, | |||
| }) | |||
| ctx.Data["Specs"] = noteBookSpecs | |||
| } | |||
| func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { | |||
| ctx.Data["PageIsNotebook"] = true | |||
| jobName := form.JobName | |||
| uuid := form.Attachment | |||
| description := form.Description | |||
| flavor := form.Flavor | |||
| count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tplModelArtsNotebookNew, &form) | |||
| return | |||
| } else { | |||
| if count >= 1 { | |||
| log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsNotebookNew, &form) | |||
| return | |||
| } | |||
| } | |||
| _, err = models.GetCloudbrainByName(jobName) | |||
| if err == nil { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsNotebookNew, &form) | |||
| return | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tplModelArtsNotebookNew, &form) | |||
| return | |||
| } | |||
| } | |||
| err = modelarts.GenerateTask(ctx, jobName, uuid, description, flavor) | |||
| if err != nil { | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsNotebookNew, &form) | |||
| return | |||
| } | |||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") | |||
| } | |||
| func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { | |||
| ctx.Data["PageIsNotebook"] = true | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| uuid := form.Attachment | |||
| description := form.Description | |||
| flavor := form.Flavor | |||
| imageId := form.ImageId | |||
| repo := ctx.Repo.Repository | |||
| @@ -182,18 +240,24 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||
| return | |||
| } | |||
| } | |||
| errStr := checkModelArtsSpecialPool(ctx, flavor, string(models.JobTypeDebug)) | |||
| if errStr != "" { | |||
| var aiCenterCode = models.AICenterOfCloudBrainTwo | |||
| if setting.ModelartsCD.Enabled { | |||
| aiCenterCode = models.AICenterOfChengdu | |||
| } | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeDebug, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: aiCenterCode}) | |||
| if err != nil || spec == nil { | |||
| notebookNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsNotebookNew, &form) | |||
| ctx.RenderWithErr("Resource specification not available", tplModelArtsNotebookNew, &form) | |||
| return | |||
| } | |||
| if setting.ModelartsCD.Enabled { | |||
| err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, flavor, imageId) | |||
| err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec) | |||
| } else { | |||
| err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, flavor, imageId) | |||
| err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec) | |||
| } | |||
| if err != nil { | |||
| @@ -240,21 +304,7 @@ func NotebookShow(ctx *context.Context) { | |||
| if err == nil { | |||
| task.User = user | |||
| } | |||
| findSpec := false | |||
| if setting.StFlavorInfo != nil { | |||
| ctx.Data["resource_spec"] = setting.StFlavorInfo.FlavorInfo[0].Desc | |||
| for _, f := range setting.StFlavorInfo.FlavorInfo { | |||
| if fmt.Sprint(f.Value) == task.FlavorCode { | |||
| ctx.Data["resource_spec"] = f.Desc | |||
| findSpec = true | |||
| break | |||
| } | |||
| } | |||
| } | |||
| setShowSpecBySpecialPoolConfig(ctx, findSpec, task) | |||
| prepareSpec4Show(ctx, task) | |||
| if task.TrainJobDuration == "" { | |||
| if task.Duration == 0 { | |||
| var duration int64 | |||
| @@ -362,6 +412,7 @@ func NotebookRestart(ctx *context.Context) { | |||
| var resultCode = "-1" | |||
| var errorMsg = "" | |||
| var status = "" | |||
| var spec *models.Specification | |||
| task := ctx.Cloudbrain | |||
| @@ -389,6 +440,28 @@ func NotebookRestart(ctx *context.Context) { | |||
| } | |||
| } | |||
| oldSpec, err := resource.GetCloudbrainSpec(task.ID) | |||
| if err != nil || oldSpec == nil { | |||
| log.Error("NotebookManage GetCloudbrainSpec error.%v", err) | |||
| errorMsg = "Resource specification not available" | |||
| break | |||
| } | |||
| aiCenterCode := models.AICenterOfCloudBrainTwo | |||
| if task.Type == models.TypeCDCenter { | |||
| aiCenterCode = models.AICenterOfChengdu | |||
| } | |||
| spec, err = resource.GetAndCheckSpec(ctx.User.ID, oldSpec.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobType(task.JobType), | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: aiCenterCode}) | |||
| if err != nil || spec == nil { | |||
| log.Error("NotebookManage GetAndCheckSpec error.task.id = %d", task.ID) | |||
| errorMsg = "Resource specification not support any more" | |||
| break | |||
| } | |||
| createTime := timeutil.TimeStampNow() | |||
| param := models.NotebookAction{ | |||
| Action: models.ActionStart, | |||
| @@ -438,8 +511,7 @@ func NotebookRestart(ctx *context.Context) { | |||
| Description: task.Description, | |||
| CreatedUnix: createTime, | |||
| UpdatedUnix: createTime, | |||
| FlavorCode: task.FlavorCode, | |||
| FlavorName: task.FlavorName, | |||
| Spec: spec, | |||
| } | |||
| err = models.RestartCloudbrain(task, newTask) | |||
| @@ -685,14 +757,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||
| } | |||
| ctx.Data["engine_versions"] = versionInfos.Version | |||
| var flavorInfos modelarts.Flavor | |||
| if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return err | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| setSpecBySpecialPoolConfig(ctx, string(models.JobTypeTrain)) | |||
| prepareCloudbrainTwoTrainSpecs(ctx) | |||
| ctx.Data["params"] = "" | |||
| ctx.Data["branchName"] = ctx.Repo.BranchName | |||
| @@ -712,6 +777,16 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||
| return nil | |||
| } | |||
| func prepareCloudbrainTwoTrainSpecs(ctx *context.Context) { | |||
| noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeTrain, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainTwo, | |||
| }) | |||
| ctx.Data["Specs"] = noteBookSpecs | |||
| } | |||
| func setMultiNodeIfConfigureMatch(ctx *context.Context) { | |||
| modelarts.InitMultiNode() | |||
| if modelarts.MultiNodeConfig != nil { | |||
| @@ -806,13 +881,7 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||
| } | |||
| ctx.Data["engine_versions"] = versionInfos.Version | |||
| var flavorInfos modelarts.Flavor | |||
| if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return err | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| setSpecBySpecialPoolConfig(ctx, string(models.JobTypeTrain)) | |||
| prepareCloudbrainTwoTrainSpecs(ctx) | |||
| configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | |||
| if err != nil { | |||
| @@ -901,14 +970,12 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||
| } | |||
| ctx.Data["engine_versions"] = versionInfos.Version | |||
| var flavorInfos modelarts.Flavor | |||
| if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return err | |||
| prepareCloudbrainTwoTrainSpecs(ctx) | |||
| spec, _ := resource.GetCloudbrainSpec(task.ID) | |||
| if spec != nil { | |||
| log.Info("spec_id = %d", spec.ID) | |||
| ctx.Data["spec_id"] = spec.ID | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| setSpecBySpecialPoolConfig(ctx, string(models.JobTypeTrain)) | |||
| var Parameters modelarts.Parameters | |||
| if err = json.Unmarshal([]byte(task.Parameters), &Parameters); err != nil { | |||
| @@ -999,13 +1066,7 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai | |||
| } | |||
| ctx.Data["engine_versions"] = versionInfos.Version | |||
| var flavorInfos modelarts.Flavor | |||
| if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return err | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| setSpecBySpecialPoolConfig(ctx, string(models.JobTypeTrain)) | |||
| prepareCloudbrainTwoTrainSpecs(ctx) | |||
| var Parameters modelarts.Parameters | |||
| if err = json.Unmarshal([]byte(form.Params), &Parameters); err != nil { | |||
| @@ -1058,7 +1119,6 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| workServerNumber := form.WorkServerNumber | |||
| engineID := form.EngineID | |||
| bootFile := strings.TrimSpace(form.BootFile) | |||
| flavorCode := form.Flavor | |||
| params := form.Params | |||
| poolID := form.PoolID | |||
| //isSaveParam := form.IsSaveParam | |||
| @@ -1111,10 +1171,14 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| return | |||
| } | |||
| errStr = checkModelArtsSpecialPool(ctx, flavorCode, string(models.JobTypeTrain)) | |||
| if errStr != "" { | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeTrain, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainTwo}) | |||
| if err != nil || spec == nil { | |||
| trainJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsTrainJobNew, &form) | |||
| ctx.RenderWithErr("Resource specification not available", tplModelArtsTrainJobNew, &form) | |||
| return | |||
| } | |||
| //Determine whether the task name of the task in the project is duplicated | |||
| @@ -1277,7 +1341,6 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| BootFileUrl: codeObsPath + bootFile, | |||
| BootFile: bootFile, | |||
| TrainUrl: outputObsPath, | |||
| FlavorCode: flavorCode, | |||
| WorkServerNumber: workServerNumber, | |||
| EngineID: int64(engineID), | |||
| LogUrl: logObsPath, | |||
| @@ -1293,6 +1356,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| VersionCount: VersionCount, | |||
| TotalVersionCount: modelarts.TotalVersionCount, | |||
| DatasetName: datasetNames, | |||
| Spec: spec, | |||
| } | |||
| userCommand, userImageUrl := getUserCommand(engineID, req) | |||
| req.UserCommand = userCommand | |||
| @@ -1427,7 +1491,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| workServerNumber := form.WorkServerNumber | |||
| engineID := form.EngineID | |||
| bootFile := strings.TrimSpace(form.BootFile) | |||
| flavorCode := form.Flavor | |||
| params := form.Params | |||
| poolID := form.PoolID | |||
| //isSaveParam := form.IsSaveParam | |||
| @@ -1465,10 +1528,14 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| return | |||
| } | |||
| errStr = checkModelArtsSpecialPool(ctx, flavorCode, string(models.JobTypeTrain)) | |||
| if errStr != "" { | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeTrain, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainTwo}) | |||
| if err != nil || spec == nil { | |||
| versionErrorDataPrepare(ctx, form) | |||
| ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsTrainJobVersionNew, &form) | |||
| ctx.RenderWithErr("Resource specification not available", tplModelArtsTrainJobVersionNew, &form) | |||
| return | |||
| } | |||
| @@ -1622,7 +1689,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| BootFileUrl: codeObsPath + bootFile, | |||
| BootFile: bootFile, | |||
| TrainUrl: outputObsPath, | |||
| FlavorCode: flavorCode, | |||
| WorkServerNumber: workServerNumber, | |||
| IsLatestVersion: isLatestVersion, | |||
| EngineID: int64(engineID), | |||
| @@ -1639,6 +1705,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||
| PreVersionName: PreVersionName, | |||
| TotalVersionCount: latestTask.TotalVersionCount + 1, | |||
| DatasetName: datasetNames, | |||
| Spec: spec, | |||
| } | |||
| userCommand, userImageUrl := getUserCommand(engineID, req) | |||
| req.UserCommand = userCommand | |||
| @@ -1822,7 +1889,6 @@ func TrainJobShow(ctx *context.Context) { | |||
| for i, task := range VersionListTasks { | |||
| var parameters models.Parameters | |||
| err := json.Unmarshal([]byte(VersionListTasks[i].Parameters), ¶meters) | |||
| if err != nil { | |||
| log.Error("Failed to Unmarshal Parameters: %s (%v)", VersionListTasks[i].Parameters, err) | |||
| @@ -1843,6 +1909,14 @@ func TrainJobShow(ctx *context.Context) { | |||
| datasetList = append(datasetList, GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)) | |||
| VersionListTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | |||
| VersionListTasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) | |||
| //add spec | |||
| s, err := resource.GetCloudbrainSpec(task.Cloudbrain.ID) | |||
| if err != nil { | |||
| log.Error("TrainJobShow GetCloudbrainSpec error:" + err.Error()) | |||
| continue | |||
| } | |||
| VersionListTasks[i].Cloudbrain.Spec = s | |||
| } | |||
| pager := context.NewPagination(VersionListCount, setting.UI.IssuePagingNum, page, 5) | |||
| @@ -2010,7 +2084,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| workServerNumber := form.WorkServerNumber | |||
| engineID := form.EngineID | |||
| bootFile := strings.TrimSpace(form.BootFile) | |||
| flavorCode := form.Flavor | |||
| params := form.Params | |||
| poolID := form.PoolID | |||
| repo := ctx.Repo.Repository | |||
| @@ -2087,13 +2160,16 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| } | |||
| } | |||
| errStr = checkModelArtsSpecialPool(ctx, flavorCode, string(models.JobTypeInference)) | |||
| if errStr != "" { | |||
| spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeInference, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainTwo}) | |||
| if err != nil || spec == nil { | |||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsInferenceJobNew, &form) | |||
| ctx.RenderWithErr("Resource specification not available", tplModelArtsInferenceJobNew, &form) | |||
| return | |||
| } | |||
| //todo: del the codeLocalPath | |||
| _, err = ioutil.ReadDir(codeLocalPath) | |||
| if err == nil { | |||
| @@ -2145,7 +2221,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| datasUrlList, dataUrl, datasetNames, isMultiDataset, err := getDatasUrlListByUUIDS(uuid) | |||
| if err != nil { | |||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||
| ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsInferenceJobNew, &form) | |||
| ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form) | |||
| return | |||
| } | |||
| dataPath := dataUrl | |||
| @@ -2201,7 +2277,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| BootFileUrl: codeObsPath + bootFile, | |||
| BootFile: bootFile, | |||
| TrainUrl: trainUrl, | |||
| FlavorCode: flavorCode, | |||
| WorkServerNumber: workServerNumber, | |||
| EngineID: int64(engineID), | |||
| LogUrl: logObsPath, | |||
| @@ -2221,6 +2296,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| ModelVersion: modelVersion, | |||
| CkptName: ckptName, | |||
| ResultUrl: resultObsPath, | |||
| Spec: spec, | |||
| DatasetName: datasetNames, | |||
| } | |||
| @@ -2401,14 +2477,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||
| } | |||
| ctx.Data["engine_versions"] = versionInfos.Version | |||
| var flavorInfos modelarts.Flavor | |||
| if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return err | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| setSpecBySpecialPoolConfig(ctx, string(models.JobTypeInference)) | |||
| prepareCloudbrainTwoInferenceSpecs(ctx) | |||
| ctx.Data["params"] = "" | |||
| ctx.Data["branchName"] = ctx.Repo.BranchName | |||
| @@ -2439,6 +2508,16 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||
| return nil | |||
| } | |||
| func prepareCloudbrainTwoInferenceSpecs(ctx *context.Context) { | |||
| noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||
| JobType: models.JobTypeInference, | |||
| ComputeResource: models.NPU, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainTwo, | |||
| }) | |||
| ctx.Data["Specs"] = noteBookSpecs | |||
| } | |||
| func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArtsInferenceJobForm) error { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| @@ -2473,14 +2552,7 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel | |||
| return err | |||
| } | |||
| ctx.Data["engine_versions"] = versionInfos.Version | |||
| var flavorInfos modelarts.Flavor | |||
| if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return err | |||
| } | |||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||
| setSpecBySpecialPoolConfig(ctx, string(models.JobTypeInference)) | |||
| prepareCloudbrainTwoInferenceSpecs(ctx) | |||
| configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | |||
| if err != nil { | |||
| @@ -2555,7 +2627,7 @@ func InferenceJobShow(ctx *context.Context) { | |||
| } else { | |||
| task.Parameters = "" | |||
| } | |||
| prepareSpec4Show(ctx, task) | |||
| LabelName := strings.Fields(task.LabelName) | |||
| ctx.Data["labelName"] = LabelName | |||
| ctx.Data["jobID"] = jobID | |||
| @@ -2,3 +2,4 @@ package response | |||
| var RESOURCE_QUEUE_NOT_AVAILABLE = &BizError{Code: 1001, Err: "resource queue not available"} | |||
| var SPECIFICATION_NOT_EXIST = &BizError{Code: 1002, Err: "specification not exist"} | |||
| var SPECIFICATION_NOT_AVAILABLE = &BizError{Code: 1003, Err: "specification not available"} | |||
| @@ -836,14 +836,12 @@ func Cloudbrains(ctx *context.Context) { | |||
| ctx.ServerError("Get job failed:", err) | |||
| return | |||
| } | |||
| models.LoadSpecs4CloudbrainInfo(ciTasks) | |||
| for i, task := range ciTasks { | |||
| ciTasks[i].CanDebug = true | |||
| ciTasks[i].CanDel = true | |||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | |||
| ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) | |||
| _, cardType, _ := repo.GetCloudbrainCardNumAndType(task.Cloudbrain) | |||
| ciTasks[i].Cloudbrain.CardType = cardType | |||
| ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) | |||
| } | |||
| @@ -2,12 +2,19 @@ package resource | |||
| import ( | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/cloudbrain" | |||
| "code.gitea.io/gitea/modules/grampus" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/modelarts" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/routers/response" | |||
| "code.gitea.io/gitea/services/admin/operate_log" | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| "strconv" | |||
| "strings" | |||
| "time" | |||
| ) | |||
| func AddResourceSpecification(doerId int64, req models.ResourceSpecificationReq) error { | |||
| @@ -92,6 +99,7 @@ func SyncGrampusSpecs(doerId int64) error { | |||
| GPUMemGiB: gpuMemGiB, | |||
| Status: models.SpecNotVerified, | |||
| IsAutomaticSync: true, | |||
| IsAvailable: true, | |||
| CreatedBy: doerId, | |||
| UpdatedBy: doerId, | |||
| }) | |||
| @@ -103,6 +111,7 @@ func SyncGrampusSpecs(doerId int64) error { | |||
| CpuCores: spec.SpecInfo.CpuCoreNum, | |||
| MemGiB: memGiB, | |||
| GPUMemGiB: gpuMemGiB, | |||
| IsAvailable: true, | |||
| UpdatedBy: doerId, | |||
| }) | |||
| } | |||
| @@ -142,7 +151,9 @@ func ResourceSpecOnShelf(doerId int64, id int64, unitPrice int) *response.BizErr | |||
| if q, err := models.GetResourceQueue(&models.ResourceQueue{ID: spec.QueueId}); err != nil || q == nil { | |||
| return response.RESOURCE_QUEUE_NOT_AVAILABLE | |||
| } | |||
| if !spec.IsAvailable { | |||
| return response.SPECIFICATION_NOT_AVAILABLE | |||
| } | |||
| err = models.ResourceSpecOnShelf(id, unitPrice) | |||
| if err != nil { | |||
| return response.NewBizError(err) | |||
| @@ -184,3 +195,461 @@ func AddSpecOperateLog(doerId int64, operateType string, newValue, oldValue *mod | |||
| Comment: comment, | |||
| }) | |||
| } | |||
| func FindAvailableSpecs(userId int64, opts models.FindSpecsOptions) ([]*models.Specification, error) { | |||
| r, err := models.FindSpecs(opts) | |||
| if err != nil { | |||
| log.Error("FindAvailableSpecs error.%v", err) | |||
| return nil, err | |||
| } | |||
| //filter exclusive specs | |||
| specs := filterExclusiveSpecs(r, userId) | |||
| //distinct by sourceSpecId | |||
| specs = distinctSpecs(specs) | |||
| return specs, err | |||
| } | |||
| func filterExclusiveSpecs(r []*models.Specification, userId int64) []*models.Specification { | |||
| specs := make([]*models.Specification, 0, len(r)) | |||
| specMap := make(map[int64]string, 0) | |||
| for i := 0; i < len(r); i++ { | |||
| spec := r[i] | |||
| if _, has := specMap[spec.ID]; has { | |||
| continue | |||
| } | |||
| if !spec.IsExclusive { | |||
| specs = append(specs, spec) | |||
| specMap[spec.ID] = "" | |||
| continue | |||
| } | |||
| orgs := strings.Split(spec.ExclusiveOrg, ";") | |||
| for _, org := range orgs { | |||
| isMember, _ := models.IsOrganizationMemberByOrgName(org, userId) | |||
| if isMember { | |||
| specs = append(specs, spec) | |||
| specMap[spec.ID] = "" | |||
| break | |||
| } | |||
| } | |||
| } | |||
| return specs | |||
| } | |||
| func distinctSpecs(r []*models.Specification) []*models.Specification { | |||
| specs := make([]*models.Specification, 0, len(r)) | |||
| sourceSpecIdMap := make(map[string]string, 0) | |||
| for i := 0; i < len(r); i++ { | |||
| spec := r[i] | |||
| if spec.SourceSpecId == "" { | |||
| specs = append(specs, spec) | |||
| continue | |||
| } | |||
| if _, has := sourceSpecIdMap[spec.SourceSpecId]; has { | |||
| continue | |||
| } | |||
| specs = append(specs, spec) | |||
| sourceSpecIdMap[spec.SourceSpecId] = "" | |||
| } | |||
| return specs | |||
| } | |||
| func GetAndCheckSpec(userId int64, specId int64, opts models.FindSpecsOptions) (*models.Specification, error) { | |||
| if specId == 0 { | |||
| return nil, nil | |||
| } | |||
| opts.SpecId = specId | |||
| r, err := FindAvailableSpecs(userId, opts) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if r == nil || len(r) == 0 { | |||
| return nil, nil | |||
| } | |||
| return r[0], nil | |||
| } | |||
| func InsertCloudbrainSpec(cloudbrainId int64, s *models.Specification) error { | |||
| c := models.CloudbrainSpec{ | |||
| CloudbrainID: cloudbrainId, | |||
| SpecId: s.ID, | |||
| SourceSpecId: s.SourceSpecId, | |||
| AccCardsNum: s.AccCardsNum, | |||
| AccCardType: s.AccCardType, | |||
| CpuCores: s.CpuCores, | |||
| MemGiB: s.MemGiB, | |||
| GPUMemGiB: s.GPUMemGiB, | |||
| ShareMemGiB: s.ShareMemGiB, | |||
| ComputeResource: s.ComputeResource, | |||
| UnitPrice: s.UnitPrice, | |||
| QueueId: s.QueueId, | |||
| QueueCode: s.QueueCode, | |||
| Cluster: s.Cluster, | |||
| AiCenterCode: s.AiCenterCode, | |||
| AiCenterName: s.AiCenterName, | |||
| IsExclusive: s.IsExclusive, | |||
| ExclusiveOrg: s.ExclusiveOrg, | |||
| } | |||
| _, err := models.InsertCloudbrainSpec(c) | |||
| if err != nil { | |||
| log.Error("InsertCloudbrainSpec error.CloudbrainSpec=%v. err=%v", c, err) | |||
| return err | |||
| } | |||
| return nil | |||
| } | |||
| func GetCloudbrainSpec(cloudbrainId int64) (*models.Specification, error) { | |||
| c, err := models.GetCloudbrainSpecByID(cloudbrainId) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if c == nil { | |||
| return nil, nil | |||
| } | |||
| return c.ConvertToSpecification(), nil | |||
| } | |||
| func RefreshHistorySpec(scopeAll bool, ids []int64) (int64, int64, error) { | |||
| var success int64 | |||
| var total int64 | |||
| if !scopeAll { | |||
| if ids == nil || len(ids) == 0 { | |||
| return 0, 0, nil | |||
| } | |||
| total = int64(len(ids)) | |||
| tasks, err := models.GetCloudbrainWithDeletedByIDs(ids) | |||
| if err != nil { | |||
| return total, 0, err | |||
| } | |||
| for _, task := range tasks { | |||
| err = RefreshOneHistorySpec(task) | |||
| if err != nil { | |||
| log.Error("RefreshOneHistorySpec error.%v", err) | |||
| continue | |||
| } | |||
| success++ | |||
| } | |||
| } else { | |||
| page := 1 | |||
| pageSize := 100 | |||
| n, err := models.CountNoSpecHistoricTask() | |||
| if err != nil { | |||
| log.Error("FindNoSpecHistoricTask CountNoSpecHistoricTask error. e=%v", err) | |||
| return 0, 0, err | |||
| } | |||
| total = n | |||
| for i := 0; i < 500; i++ { | |||
| list, err := models.FindCloudbrainTask(page, pageSize) | |||
| page++ | |||
| if err != nil { | |||
| log.Error("FindCloudbrainTask error.page=%d pageSize=%d e=%v", page, pageSize, err) | |||
| return total, success, err | |||
| } | |||
| if len(list) == 0 { | |||
| log.Info("RefreshHistorySpec. list is empty") | |||
| break | |||
| } | |||
| for _, task := range list { | |||
| s, err := GetCloudbrainSpec(task.ID) | |||
| if err != nil { | |||
| log.Error("RefreshHistorySpec GetCloudbrainSpec error.%v", err) | |||
| continue | |||
| } | |||
| if s != nil { | |||
| continue | |||
| } | |||
| err = RefreshOneHistorySpec(task) | |||
| if err != nil { | |||
| log.Error("RefreshOneHistorySpec error.%v", err) | |||
| continue | |||
| } | |||
| success++ | |||
| } | |||
| if len(list) < pageSize { | |||
| log.Info("RefreshHistorySpec. list < pageSize") | |||
| break | |||
| } | |||
| } | |||
| } | |||
| return total, success, nil | |||
| } | |||
| func RefreshOneHistorySpec(task *models.Cloudbrain) error { | |||
| var spec *models.Specification | |||
| var err error | |||
| switch task.Type { | |||
| case models.TypeCloudBrainOne: | |||
| spec, err = getCloudbrainOneSpec(task) | |||
| case models.TypeCloudBrainTwo: | |||
| spec, err = getCloudbrainTwoSpec(task) | |||
| case models.TypeC2Net: | |||
| spec, err = getGrampusSpec(task) | |||
| } | |||
| if err != nil { | |||
| log.Error("find spec error,task.ID=%d err=%v", task.ID, err) | |||
| return err | |||
| } | |||
| if spec == nil { | |||
| log.Error("find spec failed,task.ID=%d", task.ID) | |||
| return errors.New("find spec failed") | |||
| } | |||
| return InsertCloudbrainSpec(task.ID, spec) | |||
| } | |||
| func getCloudbrainOneSpec(task *models.Cloudbrain) (*models.Specification, error) { | |||
| if task.GpuQueue == "" { | |||
| log.Info("gpu queue is empty.task.ID = %d", task.ID) | |||
| return nil, nil | |||
| } | |||
| //find from config | |||
| spec, err := findCloudbrainOneSpecFromConfig(task) | |||
| if err != nil { | |||
| log.Error("getCloudbrainOneSpec findCloudbrainOneSpecFromConfig error.%v", err) | |||
| return nil, err | |||
| } | |||
| if spec != nil { | |||
| return spec, nil | |||
| } | |||
| //find from remote | |||
| return findCloudbrainOneSpecFromRemote(task) | |||
| } | |||
| func findCloudbrainOneSpecFromRemote(task *models.Cloudbrain) (*models.Specification, error) { | |||
| time.Sleep(200 * time.Millisecond) | |||
| log.Info("start findCloudbrainOneSpecFromRemote") | |||
| result, err := cloudbrain.GetJob(task.JobID) | |||
| if err != nil { | |||
| log.Error("getCloudbrainOneSpec error. %v", err) | |||
| return nil, err | |||
| } | |||
| if result == nil { | |||
| log.Info("findCloudbrainOneSpecFromRemote failed,result is empty.task.ID=%d", task.ID) | |||
| return nil, nil | |||
| } | |||
| jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | |||
| memSize, _ := models.ParseMemSizeFromGrampus(jobRes.Resource.Memory) | |||
| if task.ComputeResource == "CPU/GPU" { | |||
| task.ComputeResource = models.GPU | |||
| } | |||
| var shmMB float32 | |||
| if jobRes.Config.TaskRoles != nil && len(jobRes.Config.TaskRoles) > 0 { | |||
| shmMB = float32(jobRes.Config.TaskRoles[0].ShmMB) / 1024 | |||
| if jobRes.Config.TaskRoles[0].ShmMB == 103600 { | |||
| shmMB = 100 | |||
| } else if jobRes.Config.TaskRoles[0].ShmMB == 51800 { | |||
| shmMB = 50 | |||
| } | |||
| } | |||
| opt := models.FindSpecsOptions{ | |||
| ComputeResource: task.ComputeResource, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne, | |||
| QueueCode: task.GpuQueue, | |||
| AccCardsNum: jobRes.Resource.NvidiaComGpu, | |||
| UseAccCardsNum: true, | |||
| CpuCores: jobRes.Resource.CPU, | |||
| UseCpuCores: true, | |||
| MemGiB: memSize, | |||
| UseMemGiB: memSize > 0, | |||
| ShareMemGiB: shmMB, | |||
| UseShareMemGiB: shmMB > 0, | |||
| RequestAll: true, | |||
| } | |||
| specs, err := models.FindSpecs(opt) | |||
| if err != nil { | |||
| log.Error("getCloudbrainOneSpec from remote error,%v", err) | |||
| return nil, err | |||
| } | |||
| if len(specs) == 1 { | |||
| return specs[0], nil | |||
| } | |||
| if len(specs) == 0 { | |||
| s, err := InitQueueAndSpec(opt, "云脑一", "处理历史云脑任务时自动添加") | |||
| if err != nil { | |||
| log.Error("getCloudbrainOneSpec InitQueueAndSpec error.err=%v", err) | |||
| return nil, nil | |||
| } | |||
| return s, nil | |||
| } | |||
| log.Error("Too many results matched.size=%d opt=%+v", len(specs), opt) | |||
| return nil, nil | |||
| } | |||
| func findCloudbrainOneSpecFromConfig(task *models.Cloudbrain) (*models.Specification, error) { | |||
| //find from config | |||
| var specConfig *models.ResourceSpec | |||
| hasSpec := false | |||
| if task.JobType == string(models.JobTypeTrain) { | |||
| if cloudbrain.TrainResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.TrainResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| specConfig = tmp | |||
| break | |||
| } | |||
| } | |||
| } else if task.JobType == string(models.JobTypeInference) { | |||
| if cloudbrain.InferenceResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.InferenceResourceSpecs), &cloudbrain.InferenceResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.InferenceResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| specConfig = tmp | |||
| break | |||
| } | |||
| } | |||
| } else { | |||
| if cloudbrain.ResourceSpecs == nil { | |||
| json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||
| } | |||
| for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { | |||
| if tmp.Id == task.ResourceSpecId { | |||
| hasSpec = true | |||
| specConfig = tmp | |||
| break | |||
| } | |||
| } | |||
| } | |||
| if !hasSpec && cloudbrain.SpecialPools != nil { | |||
| for _, specialPool := range cloudbrain.SpecialPools.Pools { | |||
| if specialPool.ResourceSpec != nil { | |||
| for _, spec := range specialPool.ResourceSpec { | |||
| if task.ResourceSpecId == spec.Id { | |||
| hasSpec = true | |||
| specConfig = spec | |||
| break | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| if specConfig == nil { | |||
| log.Error("getCloudbrainOneSpec from config failed,task.ResourceSpecId=%d", task.ResourceSpecId) | |||
| return nil, nil | |||
| } | |||
| if task.ComputeResource == "CPU/GPU" { | |||
| task.ComputeResource = models.GPU | |||
| } | |||
| shareMemMiB := float32(specConfig.ShareMemMiB) / 1024 | |||
| if specConfig.ShareMemMiB == 103600 { | |||
| shareMemMiB = 100 | |||
| } else if specConfig.ShareMemMiB == 51800 { | |||
| shareMemMiB = 50 | |||
| } | |||
| opt := models.FindSpecsOptions{ | |||
| JobType: models.JobType(task.JobType), | |||
| ComputeResource: task.ComputeResource, | |||
| Cluster: models.OpenICluster, | |||
| AiCenterCode: models.AICenterOfCloudBrainOne, | |||
| QueueCode: task.GpuQueue, | |||
| AccCardsNum: specConfig.GpuNum, | |||
| UseAccCardsNum: true, | |||
| CpuCores: specConfig.CpuNum, | |||
| UseCpuCores: true, | |||
| MemGiB: float32(specConfig.MemMiB) / 1024, | |||
| UseMemGiB: true, | |||
| ShareMemGiB: shareMemMiB, | |||
| UseShareMemGiB: true, | |||
| RequestAll: true, | |||
| } | |||
| specs, err := models.FindSpecs(opt) | |||
| if err != nil { | |||
| log.Error("getCloudbrainOneSpec from config error,%v", err) | |||
| return nil, err | |||
| } | |||
| if len(specs) > 1 { | |||
| log.Error("Too many results matched.size=%d opt=%+v", len(specs), opt) | |||
| return nil, nil | |||
| } | |||
| if len(specs) == 0 { | |||
| s, err := InitQueueAndSpec(opt, "云脑一", "处理历史云脑任务时自动添加") | |||
| if err != nil { | |||
| log.Error("getCloudbrainOneSpec InitQueueAndSpec error.err=%v", err) | |||
| return nil, nil | |||
| } | |||
| return s, nil | |||
| } | |||
| return specs[0], nil | |||
| } | |||
| func getCloudbrainTwoSpec(task *models.Cloudbrain) (*models.Specification, error) { | |||
| specMap, err := models.GetCloudbrainTwoSpecs() | |||
| if err != nil { | |||
| log.Error("InitCloudbrainTwoSpecs err.%v", err) | |||
| return nil, err | |||
| } | |||
| if task.FlavorCode != "" { | |||
| return specMap[task.FlavorCode], nil | |||
| } | |||
| time.Sleep(200 * time.Millisecond) | |||
| log.Info("start getCloudbrainTwoSpec FromRemote") | |||
| if task.JobType == string(models.JobTypeDebug) { | |||
| result, err := modelarts.GetNotebook2(task.JobID) | |||
| if err != nil { | |||
| log.Error("getCloudbrainTwoSpec GetNotebook2 error.%v", err) | |||
| return nil, err | |||
| } | |||
| if result != nil { | |||
| return specMap[result.Flavor], nil | |||
| } | |||
| } else if task.JobType == string(models.JobTypeTrain) || task.JobType == string(models.JobTypeInference) { | |||
| result, err := modelarts.GetTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | |||
| if err != nil { | |||
| log.Error("getCloudbrainTwoSpec GetTrainJob error:%v", task.JobName, err) | |||
| return nil, err | |||
| } | |||
| if result != nil { | |||
| return specMap[result.Flavor.Code], nil | |||
| } | |||
| } | |||
| return nil, nil | |||
| } | |||
| func getGrampusSpec(task *models.Cloudbrain) (*models.Specification, error) { | |||
| specMap, err := models.GetGrampusSpecs() | |||
| if err != nil { | |||
| log.Error("GetGrampusSpecs err.%v", err) | |||
| return nil, err | |||
| } | |||
| if task.AiCenter != "" { | |||
| c := strings.Split(task.AiCenter, "+") | |||
| spec := specMap[task.FlavorCode+"_"+c[0]] | |||
| if spec != nil { | |||
| return spec, nil | |||
| } | |||
| } | |||
| return specMap[task.FlavorCode], nil | |||
| } | |||
| func InitQueueAndSpec(opt models.FindSpecsOptions, aiCenterName string, remark string) (*models.Specification, error) { | |||
| return models.InitQueueAndSpec(models.ResourceQueue{ | |||
| QueueCode: opt.QueueCode, | |||
| Cluster: opt.Cluster, | |||
| AiCenterCode: opt.AiCenterCode, | |||
| AiCenterName: aiCenterName, | |||
| ComputeResource: opt.ComputeResource, | |||
| AccCardType: models.GetCloudbrainOneAccCardType(opt.QueueCode), | |||
| Remark: remark, | |||
| }, models.ResourceSpecification{ | |||
| AccCardsNum: opt.AccCardsNum, | |||
| CpuCores: opt.CpuCores, | |||
| MemGiB: opt.MemGiB, | |||
| GPUMemGiB: opt.GPUMemGiB, | |||
| ShareMemGiB: opt.ShareMemGiB, | |||
| Status: models.SpecOffShelf, | |||
| IsAvailable: true, | |||
| }) | |||
| } | |||
| @@ -1,4 +1,5 @@ | |||
| {{template "base/head" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <!-- 弹窗 --> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| @@ -175,10 +176,17 @@ | |||
| </div> | |||
| <!-- XPU类型 --> | |||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||
| <span style="font-size: 12px;" title="{{.CardType}}"> | |||
| {{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||
| </span> | |||
| </div> | |||
| <span style="font-size: 12px;" title="" class="card_type_{{.DisplayJobName}}_{{$JobID}}"></span> | |||
| </div> | |||
| <script> | |||
| (function(){ | |||
| var spec = {{.Spec}} || {}; | |||
| var cardType = getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType) || '--'; | |||
| var spanEl = document.querySelector('.card_type_{{.DisplayJobName}}_{{$JobID}}'); | |||
| spanEl.setAttribute('title', cardType); | |||
| spanEl.innerText = cardType; | |||
| })(); | |||
| </script> | |||
| <!-- 创建者 --> | |||
| <div class="one wide column text center nowrap" style="width:4% !important;"> | |||
| {{if .User.Name}} | |||
| @@ -4,7 +4,7 @@ | |||
| {{template "admin/navbar" .}} | |||
| <div class="ui container"> | |||
| <div id="__vue-root"></div> | |||
| </duv> | |||
| </div> | |||
| </div> | |||
| <script src="{{StaticUrlPrefix}}/js/vp-resources-queue.js?v={{MD5 AppVer}}"></script> | |||
| {{template "base/footer" .}} | |||
| @@ -4,7 +4,7 @@ | |||
| {{template "admin/navbar" .}} | |||
| <div class="ui container"> | |||
| <div id="__vue-root"></div> | |||
| </duv> | |||
| </div> | |||
| </div> | |||
| <script src="{{StaticUrlPrefix}}/js/vp-resources-scene.js?v={{MD5 AppVer}}"></script> | |||
| {{template "base/footer" .}} | |||
| @@ -4,7 +4,7 @@ | |||
| {{template "admin/navbar" .}} | |||
| <div class="ui container"> | |||
| <div id="__vue-root"></div> | |||
| </duv> | |||
| </div> | |||
| </div> | |||
| <script src="{{StaticUrlPrefix}}/js/vp-resources-specification.js?v={{MD5 AppVer}}"></script> | |||
| {{template "base/footer" .}} | |||
| @@ -0,0 +1,25 @@ | |||
| <div style="display:inline-block;"> | |||
| <div style="display:flex;align-items:center;color:#f2711c;"> | |||
| <i class="ri-error-warning-line" style="margin-right: 0.5rem; font-size: 14px"></i> | |||
| <span style="font-size: 12px">{{.i18n.Tr "repo.wait_count_start"}} <span class="__task_wait_count__">{{.WaitCount}}</span> {{.i18n.Tr "repo.wait_count_end"}}</span> | |||
| </div> | |||
| </div> | |||
| <script> | |||
| ;(function() { | |||
| var queuesDetail = {{.QueuesDetail}}; | |||
| if (queuesDetail) { | |||
| function changeSpecs() { | |||
| var specsSelEl = $('select#__specs__'); | |||
| var seldOption = specsSelEl.find('option:selected'); | |||
| var queueCode = seldOption.attr('queueCode'); | |||
| $('span.__task_wait_count__').text(queuesDetail[queueCode] || 0); | |||
| }; | |||
| $('body').on('change', 'select#__specs__', function(e) { | |||
| changeSpecs(); | |||
| }); | |||
| setTimeout(function() { | |||
| changeSpecs(); | |||
| }, 50); | |||
| } | |||
| })(); | |||
| </script> | |||
| @@ -51,9 +51,12 @@ | |||
| <a class="active item model_benchmark" | |||
| href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $ "type" .benchmark_gpu_types}} | |||
| </div> | |||
| <div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
| @@ -71,7 +74,7 @@ | |||
| onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <!--<div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown width48" placeholder="选择GPU类型" | |||
| name="gpu_type"> | |||
| @@ -79,7 +82,7 @@ | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div>--> | |||
| <div class="required unite min_title two inline fields" style="margin-left: 80px;"> | |||
| <div class="required ten wide field" style="width: 26.5% !important;"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||
| @@ -112,7 +115,7 @@ | |||
| <div id="images-new-cb"> | |||
| </div> | |||
| {{template "custom/select_dataset_train" .}} | |||
| <div class="required min_title inline field" style="margin-top:2rem;"> | |||
| <!--<div class="required min_title inline field" style="margin-top:2rem;"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
| @@ -123,6 +126,13 @@ | |||
| </option> | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required min_title inline field" style="margin-top:2rem;"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="__specs__" class="ui search dropdown width48" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||
| name="spec_id"> | |||
| </select> | |||
| </div> | |||
| <div class="inline min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| @@ -146,10 +156,13 @@ | |||
| <a class="item model_benchmark" | |||
| href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $ "type" .benchmark_gpu_types}} | |||
| </div> | |||
| <div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
| @@ -167,7 +180,7 @@ | |||
| onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <!--<div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" | |||
| style='width:385px' name="gpu_type"> | |||
| @@ -175,7 +188,7 @@ | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div>--> | |||
| <div class="required unite inline min_title fields" style="width: 90%;margin-left: 5.7rem;"> | |||
| <div class="required eight wide field"> | |||
| <label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label> | |||
| @@ -201,7 +214,7 @@ | |||
| <div id="images-new-cb"> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <!--<div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
| @@ -212,6 +225,14 @@ | |||
| </option> | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="__specs__" class="ui search dropdown width48" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||
| name="spec_id"> | |||
| </select> | |||
| </div> | |||
| <div class="inline min_title field required"> | |||
| @@ -245,7 +266,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| let createFlag = false | |||
| @@ -304,6 +325,7 @@ | |||
| } | |||
| } | |||
| } | |||
| var isValidate = false; | |||
| function validate() { | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -327,12 +349,18 @@ | |||
| } | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function () { | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function (e) { | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -342,4 +370,16 @@ | |||
| $('.ui.create_train_job.green.button').click(function (e) { | |||
| validate() | |||
| }) | |||
| ;(function() { | |||
| var SPECS = {{ .benchmark_specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -454,7 +454,7 @@ | |||
| {{$.i18n.Tr "cloudbrain.gpu_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content resorce_type"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_type}} | |||
| </div> | |||
| @@ -465,9 +465,9 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_spec}} | |||
| {{$.resource_spec}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| @@ -595,7 +595,22 @@ | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| ;(function() { | |||
| var SPEC = {{ $.Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec div').text(specStr); | |||
| $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| })(); | |||
| </script> | |||
| <script> | |||
| $('.menu .item').tab() | |||
| @@ -630,4 +645,5 @@ | |||
| }); | |||
| } | |||
| </script> | |||
| @@ -82,8 +82,11 @@ | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $ "type" .inference_gpu_types}} | |||
| <div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
| </div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;"> | |||
| <i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
| <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_infer_gpu_tooltips" "/dataset" "/model" "/result" | Safe}}</span> | |||
| </div> | |||
| @@ -140,7 +143,7 @@ | |||
| <span > | |||
| <i class="question circle icon" data-content="{{.i18n.Tr "cloudbrain.model_file_postfix_rule"}}" data-position="top center" data-variation="inverted mini"></i> | |||
| </span> | |||
| </div> | |||
| <!-- AI引擎 --> | |||
| <div id="images-new-cb"> | |||
| @@ -168,7 +171,7 @@ | |||
| </select> | |||
| </div> | |||
| <!-- GPU 卡的类型 --> | |||
| <div class="required min_title inline field"> | |||
| <!--<div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search width48 dropdown gpu-type" placeholder="选择GPU类型" | |||
| style='width:385px' name="gpu_type"> | |||
| @@ -189,7 +192,7 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div>--> | |||
| <!-- 数据集--> | |||
| <div id="select-multi-dataset"> | |||
| @@ -227,7 +230,7 @@ | |||
| </select> | |||
| </div> | |||
| <!-- 规格 --> | |||
| <div class="required min_title inline field"> | |||
| <!--<div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown width80" placeholder="选择资源规格" name="resource_spec_id"> | |||
| {{if .resource_spec_id}} | |||
| @@ -248,8 +251,12 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="__specs__" class="ui search dropdown width48" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" ovalue="{{.spec_id}}" name="spec_id"> | |||
| </select> | |||
| </div> | |||
| <!-- 表单操作 --> | |||
| <div class="inline min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| @@ -264,7 +271,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| let createFlag = false | |||
| @@ -299,7 +306,7 @@ | |||
| $('#select_model').removeClass("loading") | |||
| }) | |||
| }) | |||
| // 根据选中的模型名称获取相应的模型版本 | |||
| function modelVersion(){ | |||
| let faildModelVersion = $('#failed_model_version').val() | |||
| @@ -318,7 +325,7 @@ | |||
| $("#select_model_version").removeClass("loading") | |||
| const initVersionText = $('#model_name_version div.item:first-child').text() | |||
| const initVersionValue = $('#model_name_version div.item:first-child').data('value') | |||
| if(faildModelVersion&&faildTrainUrl){ | |||
| $("#select_model_version").dropdown('set text',faildModelVersion) | |||
| $("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | |||
| @@ -381,7 +388,7 @@ | |||
| params&¶ms.parameter.forEach((item,index)=>{ | |||
| Add_parameter(index,flag=true,item) | |||
| }) | |||
| }) | |||
| // 参数增加、删除、修改、保存 | |||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||
| @@ -436,6 +443,8 @@ | |||
| msg = JSON.stringify(msg) | |||
| $('#store_run_para').val(msg) | |||
| } | |||
| var isValidate = false; | |||
| function validate(){ | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -489,12 +498,18 @@ | |||
| type: 'empty', | |||
| } | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function(e){ | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -509,4 +524,15 @@ | |||
| send_run_para(); | |||
| validate(); | |||
| }) | |||
| ;(function() { | |||
| var SPECS = {{ .inference_specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -341,7 +341,7 @@ | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content resorce_type"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_type}} | |||
| </div> | |||
| @@ -483,7 +483,7 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{$.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{$.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{$.ShareMemMiB}} | |||
| </div> | |||
| @@ -599,6 +599,7 @@ | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| $('.menu .item').tab() | |||
| @@ -659,4 +660,17 @@ | |||
| document.getElementById("info_display").innerHTML = html; | |||
| } | |||
| ;(function() { | |||
| var SPEC = {{ .Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec div').text(specStr); | |||
| $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| })(); | |||
| </script> | |||
| @@ -25,7 +25,7 @@ | |||
| <div class="column"> | |||
| <div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div> | |||
| {{template "base/alert" .}} | |||
| <div class="ui negative message" id="messageInfo"> | |||
| <div class="ui negative message" id="messageInfo" style="display:none;"> | |||
| <p></p> | |||
| </div> | |||
| <form id="form_id" class="ui form" action="{{.Link}}" method="post"> | |||
| @@ -55,8 +55,11 @@ | |||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count" .}} | |||
| </div> | |||
| </div> | |||
| <div class="inline field"> | |||
| <label></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||
| @@ -108,8 +111,8 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="inline required field"> | |||
| </div> | |||
| <!--<div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown gpu-type" placeholder="选择GPU类型" | |||
| style='width:385px' name="gpu_type"> | |||
| @@ -117,7 +120,7 @@ | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div>--> | |||
| <div id="images-new-cb"> | |||
| @@ -125,8 +128,8 @@ | |||
| <div id="select-multi-dataset"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <!--<div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
| @@ -137,6 +140,14 @@ | |||
| </option> | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="__specs__" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||
| name="spec_id"> | |||
| </select> | |||
| </div> | |||
| <div class="inline required field"> | |||
| @@ -188,6 +199,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| $('#messageInfo').css('display', 'none') | |||
| @@ -196,6 +208,7 @@ | |||
| context.value = '' | |||
| $(".icon.icons").css("visibility", "hidden") | |||
| } | |||
| var isValidate = false; | |||
| function validate(){ | |||
| $('.ui.form').form({ | |||
| on: 'blur', | |||
| @@ -207,11 +220,17 @@ | |||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||
| } | |||
| ] | |||
| }, | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| onSuccess: function(){ | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function(e){ | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -219,6 +238,7 @@ | |||
| validate(); | |||
| let createFlag = false | |||
| form.onsubmit = function (e) { | |||
| if (!isValidate) return false; | |||
| if(createFlag) return false | |||
| let value_task = $("input[name='display_job_name']").val() | |||
| let value_image = $("input[name='image']").val() | |||
| @@ -286,7 +306,18 @@ | |||
| } | |||
| selected_value = $("#cloudbrain_benchmark_category").val() | |||
| $('#store_category').attr("value", selected_value) | |||
| validate(); | |||
| }) | |||
| ;(function() { | |||
| var SPECS = {{ .debug_specs }}; | |||
| var showPoint = true; | |||
| window.renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -345,7 +345,7 @@ | |||
| {{$.i18n.Tr "cloudbrain.gpu_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content resorce_type"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_type}} | |||
| </div> | |||
| @@ -400,10 +400,8 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{$.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{$.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{$.ShareMemMiB}} | |||
| </div> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| @@ -560,7 +558,7 @@ | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| $('.menu .item').tab() | |||
| $(document).ready(function () { | |||
| @@ -601,4 +599,17 @@ | |||
| } | |||
| document.getElementById("info_display").innerHTML = html; | |||
| } | |||
| ;(function() { | |||
| var SPEC = {{ .Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec div').text(specStr); | |||
| $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| })(); | |||
| </script> | |||
| @@ -14,7 +14,9 @@ | |||
| .width { | |||
| width: 100% !important; | |||
| } | |||
| .width48 { | |||
| width: 48.5% !important; | |||
| } | |||
| .width80 { | |||
| width: 80.7% !important; | |||
| margin-left: 10px; | |||
| @@ -30,7 +32,7 @@ | |||
| margin-left: 10.5rem !important; | |||
| align-items: center; | |||
| } | |||
| .width81 { | |||
| margin-left: 1.5rem !important; | |||
| width: 81% !important; | |||
| @@ -114,8 +116,11 @@ | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $ "type" .train_gpu_types}} | |||
| <div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
| </div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;"> | |||
| <i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
| <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/code" "/dataset" "/model" | Safe}}</span> | |||
| </div> | |||
| @@ -171,7 +176,7 @@ | |||
| <option name="job_type" value="TRAIN">TRAIN</option> | |||
| </select> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <!--<div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search width806 dropdown gpu-type" placeholder="选择GPU类型" | |||
| style='width:385px' name="gpu_type"> | |||
| @@ -192,7 +197,7 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div>--> | |||
| <div id="images-new-cb"> | |||
| </div> | |||
| @@ -224,10 +229,10 @@ | |||
| class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
| <input id="store_run_para" type="hidden" name="run_para_list"> | |||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | |||
| </div> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <!--<div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" | |||
| style='width:385px' name="resource_spec_id"> | |||
| @@ -249,6 +254,13 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="__specs__" class="ui dropdown width48" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" ovalue="{{.spec_id}}" | |||
| name="spec_id"> | |||
| </select> | |||
| </div> | |||
| <div class="inline field" style="padding: 1rem 0;"> | |||
| @@ -267,7 +279,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| let createFlag = false | |||
| @@ -282,7 +294,7 @@ | |||
| .tab(); | |||
| $(document).keydown(function(event){ | |||
| switch(event.keyCode){ | |||
| case 13:return false; | |||
| case 13:return false; | |||
| } | |||
| }); | |||
| $(document).ready(function(){ | |||
| @@ -290,7 +302,7 @@ | |||
| params&¶ms.parameter.forEach((item,index)=>{ | |||
| Add_parameter(index,flag=true,item) | |||
| }) | |||
| }) | |||
| // 参数增加、删除、修改、保存 | |||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||
| @@ -342,7 +354,8 @@ | |||
| $('select.dropdown') | |||
| .dropdown(); | |||
| var isValidate = false; | |||
| function validate() { | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -388,13 +401,19 @@ | |||
| type: 'empty', | |||
| } | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function () { | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function (e) { | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -419,6 +438,17 @@ | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function (e) { | |||
| send_run_para(); | |||
| validate(); | |||
| validate(); | |||
| }) | |||
| </script> | |||
| ;(function() { | |||
| var SPECS = {{ .train_specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -359,7 +359,7 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content resorce_type"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_type}} | |||
| </div> | |||
| @@ -370,7 +370,7 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{$.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{$.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{$.ShareMemMiB}} | |||
| </div> | |||
| @@ -677,6 +677,7 @@ | |||
| {{template "base/footer" .}} | |||
| <script type="text/javascript" src="/self/ztree/js/jquery.ztree.core.js"></script> | |||
| <script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.js"></script> | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| var setting = { | |||
| @@ -987,4 +988,17 @@ | |||
| document.getElementById("info_display").innerHTML = html; | |||
| } | |||
| ;(function() { | |||
| var SPEC = {{ .Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec div').text(specStr); | |||
| $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| })(); | |||
| </script> | |||
| @@ -30,7 +30,9 @@ | |||
| .width81{ | |||
| width: 81% !important; | |||
| } | |||
| .width48{ | |||
| width: 48.5% !important; | |||
| } | |||
| .add{font-size: 18px; | |||
| padding: 0.5rem; | |||
| border: 1px solid rgba(187, 187, 187, 100); | |||
| @@ -104,9 +106,12 @@ | |||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $}} | |||
| <div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
| </div> | |||
| </div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;"> | |||
| <i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
| <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/tmp/code" "/tmp/dataset" "/tmp/output" | Safe}}</span> | |||
| </div> | |||
| @@ -116,7 +121,7 @@ | |||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="36"> | |||
| <span class="tooltips" style="margin-left: 11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||
| </div> | |||
| <div class="min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
| {{if .description}} | |||
| @@ -128,7 +133,7 @@ | |||
| <div class="ui divider"></div> | |||
| <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||
| @@ -167,7 +172,7 @@ | |||
| <a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/train_for_c2net.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| {{template "custom/select_dataset_train" .}} | |||
| <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
| <div class="inline min_title field"> | |||
| @@ -175,11 +180,10 @@ | |||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
| <input id="store_run_para" type="hidden" name="run_para_list"> | |||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | |||
| </div> | |||
| </div> | |||
| <div class="required min_title inline field" id="flavor_name"> | |||
| <!--<div class="required min_title inline field" id="flavor_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | |||
| {{if .flavor}} | |||
| @@ -199,8 +203,12 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required min_title inline field" id="flavor_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width48" id="__specs__" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||
| </div> | |||
| <div class="inline min_title field"> | |||
| <label class="label-fix-width"></label> | |||
| <button class="ui create_train_job green button"> | |||
| @@ -208,14 +216,15 @@ | |||
| </button> | |||
| <a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| </div> | |||
| <!-- 模态框 --> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| @@ -230,13 +239,13 @@ | |||
| $('.menu .item') | |||
| .tab(); | |||
| $(document).ready(function(){ | |||
| let params = $('.dynamic.field').data('params') | |||
| params&¶ms.parameter.forEach((item,index)=>{ | |||
| Add_parameter(index,flag=true,item) | |||
| }) | |||
| }) | |||
| // 参数增加、删除、修改、保存 | |||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||
| @@ -287,6 +296,7 @@ | |||
| $('select.dropdown') | |||
| .dropdown(); | |||
| var isValidate = false; | |||
| function validate(){ | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -333,13 +343,19 @@ | |||
| type : 'integer[1..25]', | |||
| } | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function(e){ | |||
| onFailure: function(e){ | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -374,4 +390,16 @@ | |||
| send_run_para() | |||
| validate(); | |||
| }) | |||
| </script> | |||
| ;(function() { | |||
| var SPECS = {{ .Specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -25,7 +25,9 @@ | |||
| .width81{ | |||
| width: 81% !important; | |||
| } | |||
| .width48 { | |||
| width: 48.5% !important; | |||
| } | |||
| .add{font-size: 18px; | |||
| padding: 0.5rem; | |||
| border: 1px solid rgba(187, 187, 187, 100); | |||
| @@ -99,13 +101,15 @@ | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $}} | |||
| <div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
| </div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;"> | |||
| <i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
| <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/cache/code" "/cache/dataset" "/cache/output" | Safe}}</span> | |||
| </div> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="36"> | |||
| @@ -179,7 +183,7 @@ | |||
| </span> | |||
| <a href="https://git.openi.org.cn/OpenIOSSG/MNIST_Example/src/branch/master/train_for_c2net.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| {{template "custom/select_dataset_train" .}} | |||
| <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
| <div class="inline min_title field"> | |||
| @@ -187,11 +191,11 @@ | |||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
| <input id="store_run_para" type="hidden" name="run_para_list"> | |||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | |||
| </div> | |||
| </div> | |||
| <div class="required min_title inline field" id="flavor_name"> | |||
| <!--<div class="required min_title inline field" id="flavor_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | |||
| {{if .flavor}} | |||
| @@ -211,6 +215,10 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required min_title inline field" id="flavor_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width48" id="__specs__" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||
| </div> | |||
| <div class="inline required min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||
| @@ -242,6 +250,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| @@ -256,13 +265,13 @@ | |||
| $('.menu .item') | |||
| .tab(); | |||
| $(document).ready(function(){ | |||
| let params = $('.dynamic.field').data('params') | |||
| params&¶ms.parameter.forEach((item,index)=>{ | |||
| Add_parameter(index,flag=true,item) | |||
| }) | |||
| }) | |||
| // 参数增加、删除、修改、保存 | |||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||
| @@ -309,10 +318,11 @@ | |||
| $(this).popup('show') | |||
| }); | |||
| $('select.dropdown') | |||
| .dropdown(); | |||
| var isValidate = false; | |||
| function validate(){ | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -350,13 +360,19 @@ | |||
| type : 'integer[1..25]', | |||
| } | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function(e){ | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -395,4 +411,16 @@ | |||
| send_run_para() | |||
| validate(); | |||
| }) | |||
| ;(function() { | |||
| var SPECS = {{ .Specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -357,7 +357,7 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"> | |||
| {{.FlavorName}} | |||
| </div> | |||
| @@ -634,8 +634,20 @@ | |||
| {{template "base/footer" .}} | |||
| <script type="text/javascript" src="/self/ztree/js/jquery.ztree.core.js"></script> | |||
| <script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.js"></script> | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| ;(function() { | |||
| var SPEC = {{ .Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec').text(specStr); | |||
| })(); | |||
| var setting = { | |||
| check: { | |||
| enable: true, | |||
| @@ -83,8 +83,11 @@ | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $}} | |||
| <div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
| </div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;"> | |||
| <i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
| <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.infer_dataset_path_rule" | Safe}}</span> | |||
| </div> | |||
| @@ -196,7 +199,7 @@ | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <!-- 数据集 --> | |||
| <div id="select-multi-dataset"> | |||
| @@ -249,7 +252,7 @@ | |||
| </select> | |||
| </div> | |||
| <!-- 规格 --> | |||
| <div class="required min_title inline field" id="flaver_name"> | |||
| <!--<div class="required min_title inline field" id="flaver_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width80" id="trainjob-flavor" name="flavor"> | |||
| {{if .flavor}} | |||
| @@ -269,6 +272,10 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required min_title inline field" id="flaver_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width48" id="__specs__" name="spec_id" ovalue="{{.spec_id}}"></select> | |||
| </div> | |||
| <!-- 计算节点 --> | |||
| <div class="inline required min_title field"> | |||
| @@ -292,7 +299,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| let createFlag = false | |||
| @@ -305,7 +312,7 @@ | |||
| let nameMap,nameList | |||
| $(".ui.button").attr('href',url_href) | |||
| // 获取模型列表和模型名称对应的模型版本 | |||
| $(document).ready(function(){ | |||
| modelVersion() | |||
| modelCkpt() | |||
| @@ -330,7 +337,7 @@ | |||
| $('#select_model').removeClass("loading") | |||
| }) | |||
| }) | |||
| // 根据选中的模型名称获取相应的模型版本 | |||
| function modelVersion(){ | |||
| let faildModelVersion = $('#failed_model_version').val() | |||
| @@ -349,7 +356,7 @@ | |||
| $("#select_model_version").removeClass("loading") | |||
| const initVersionText = $('#model_name_version div.item:first-child').text() | |||
| const initVersionValue = $('#model_name_version div.item:first-child').data('value') | |||
| if(faildModelVersion&&faildTrainUrl){ | |||
| $("#select_model_version").dropdown('set text',faildModelVersion) | |||
| $("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | |||
| @@ -458,6 +465,8 @@ | |||
| $("input#ai_engine_name").val(name1) | |||
| $("input#ai_flaver_name").val(name2) | |||
| } | |||
| var isValidate = false; | |||
| function validate(){ | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -511,12 +520,18 @@ | |||
| type: 'empty', | |||
| } | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function(e){ | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -532,4 +547,16 @@ | |||
| get_name() | |||
| validate(); | |||
| }) | |||
| ;(function() { | |||
| var SPECS = {{ .Specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -423,7 +423,7 @@ td, th { | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"> | |||
| {{.FlavorName}} | |||
| </div> | |||
| @@ -522,6 +522,7 @@ td, th { | |||
| <!-- 确认模态框 --> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| console.log('{{$.canDownload}}') | |||
| $(document).ready(function(){ | |||
| @@ -538,5 +539,17 @@ $(document).ready(function(){ | |||
| repoPath = urlArr.slice(-4)[0] | |||
| jobID = urlArr.slice(-1)[0] | |||
| }) | |||
| ;(function() { | |||
| var SPEC = {{ .Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec div').text(specStr); | |||
| // $('td.ti-text-form-content.resorce_type').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| })(); | |||
| </script> | |||
| @@ -38,7 +38,10 @@ | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count" .}} | |||
| </div> | |||
| <div class="inline field"> | |||
| <label></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||
| @@ -65,7 +68,7 @@ | |||
| <label>类型</label> | |||
| <input name="job_type" id="cloudbrain_job_type" value="{{.notebook_type}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> --> | |||
| <div class="inline required field"> | |||
| <!--<div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.specification"}}</label> | |||
| <select id="cloudbrain_flavor" class="ui search dropdown" placeholder="选择规格" style='width:385px' name="flavor"> | |||
| {{range .flavors}} | |||
| @@ -73,6 +76,10 @@ | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.specification"}}</label> | |||
| <select id="__specs__" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||
| </div> | |||
| <!--<div class="inline required field"> | |||
| <label>数据集存放路径</label> | |||
| @@ -95,13 +102,14 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| // 判断必填选项是否填写正确 | |||
| let form = document.getElementById('form_id'); | |||
| $('#messageInfo').css('display','none') | |||
| var isValidate = false; | |||
| function validate(){ | |||
| $('.ui.form').form({ | |||
| on: 'blur', | |||
| @@ -113,11 +121,17 @@ | |||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||
| } | |||
| ] | |||
| }, | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| onSuccess: function(){ | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function(e){ | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -125,7 +139,8 @@ | |||
| validate(); | |||
| let createFlag = false | |||
| form.onsubmit = function(e){ | |||
| if(createFlag) return false | |||
| if(!isValidate) return false; | |||
| if(createFlag) return false; | |||
| let value_task = $("input[name='display_job_name']").val() | |||
| let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | |||
| let flag = re.test(value_task) | |||
| @@ -171,4 +186,16 @@ | |||
| } | |||
| }); | |||
| }); | |||
| ;(function() { | |||
| var SPECS = {{ .Specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -350,14 +350,14 @@ | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn-image" style="cursor:pointer" | |||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn-image" style="cursor:pointer" | |||
| data-clipboard-text="{{.Image}}" | |||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||
| data-variation="inverted tiny" | |||
| > | |||
| <span title="{{.Image}}">{{.Image}}</span> | |||
| <span title="{{.Image}}">{{.Image}}</span> | |||
| </span> | |||
| </div> | |||
| </td> | |||
| @@ -367,7 +367,7 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_spec}} | |||
| </div> | |||
| @@ -427,7 +427,7 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div style="clear:both"> | |||
| <table style="border:none" class="ui fixed small stackable table"> | |||
| @@ -437,7 +437,7 @@ | |||
| <th style="color: #8a8e99;font-size:12px" class="two wide center aligned">{{$.i18n.Tr "dataset.download_oper"}}</th> | |||
| </tr></thead> | |||
| <tbody> | |||
| {{range $.datasetDownload}} | |||
| {{range $.datasetDownload}} | |||
| <tr> | |||
| <td style="word-wrap: break-word;word-break: break-all;"> | |||
| @@ -488,7 +488,7 @@ | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| $('.menu .item').tab() | |||
| @@ -498,4 +498,19 @@ | |||
| $(document).ready(function () { | |||
| $('.secondary.menu .item').tab(); | |||
| }); | |||
| </script> | |||
| console.log({{$.datasetDownload}}) | |||
| ;(function() { | |||
| var SPEC = {{ .Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec div').text(specStr); | |||
| $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| })(); | |||
| </script> | |||
| @@ -88,7 +88,7 @@ | |||
| </a> | |||
| </div> | |||
| </div> | |||
| <div class="required inline min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
| <div class="ui blue mini menu compact selectcloudbrain"> | |||
| @@ -109,9 +109,12 @@ | |||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| {{template "custom/wait_count_train" Dict "ctx" $}} | |||
| <div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
| </div> | |||
| </div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;"> | |||
| <i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
| <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.train_dataset_path_rule" | Safe}}</span> | |||
| </div> | |||
| @@ -203,7 +206,7 @@ | |||
| </span> | |||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| <div id="select-multi-dataset"> | |||
| </div> | |||
| @@ -257,7 +260,7 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="required inline min_title field" id="flaver_name"> | |||
| <!--<div class="required inline min_title field" id="flaver_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width48" id="trainjob-flavor" name="flavor"> | |||
| {{if .flavor}} | |||
| @@ -277,6 +280,10 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required inline min_title field" id="flaver_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width48" id="__specs__" name="spec_id" ovalue="{{.spec_id}}"></select> | |||
| </div> | |||
| <div class="inline required min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||
| @@ -326,7 +333,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| let createFlag = false | |||
| @@ -343,7 +350,7 @@ | |||
| .tab(); | |||
| $(document).keydown(function(event){ | |||
| switch(event.keyCode){ | |||
| case 13:return false; | |||
| case 13:return false; | |||
| } | |||
| }); | |||
| // 参数增加、删除、修改、保存 | |||
| @@ -457,6 +464,7 @@ | |||
| $('select.dropdown') | |||
| .dropdown(); | |||
| var isValidate = false; | |||
| function validate() { | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -494,13 +502,19 @@ | |||
| type: 'integer[1..25]', | |||
| } | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function () { | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function (e) { | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -539,4 +553,16 @@ | |||
| send_run_para(); | |||
| validate(); | |||
| }) | |||
| </script> | |||
| ;(function() { | |||
| var SPECS = {{ .Specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -1,5 +1,7 @@ | |||
| {{template "base/head" .}} | |||
| <link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css"> | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <style> | |||
| .according-panel-heading { | |||
| box-sizing: border-box; | |||
| @@ -395,11 +397,26 @@ | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <td class="ti-text-form-content spec{{$k}}"> | |||
| <div class="text-span text-span-w"> | |||
| {{.FlavorName}} | |||
| </div> | |||
| </td> | |||
| <script> | |||
| ;(function() { | |||
| var SPEC = {{ .Spec }}; | |||
| var showPoint = true; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec{{$k}} div').text(specStr); | |||
| // $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| })(); | |||
| </script> | |||
| </tr> | |||
| </tbody> | |||
| @@ -73,7 +73,6 @@ | |||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||
| <input type="hidden" id="display_job_name" name="display_job_name" value="{{.display_job_name}}"> | |||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||
| <div class="required min_title inline field"> | |||
| <label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | |||
| @@ -108,12 +107,12 @@ | |||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div style="margin-top:-5px;"> | |||
| {{template "custom/wait_count_train" Dict "ctx" $}} | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: -0.5rem;"> | |||
| {{template "custom/task_wait_count" .}} | |||
| </div> | |||
| <div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;margin-bottom: 1.5rem;"> | |||
| <div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;margin-bottom: 1.5rem;"> | |||
| <i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
| <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.train_dataset_path_rule" | Safe}}</span> | |||
| </div> | |||
| @@ -249,7 +248,7 @@ | |||
| </div> | |||
| </div> | |||
| <div class="required unite min_title inline field" id="flaver_name"> | |||
| <!--<div class="required unite min_title inline field" id="flaver_name"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | |||
| {{if .flavor_name}} | |||
| @@ -261,6 +260,10 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div>--> | |||
| <div class="required unite min_title inline field" id="flaver_name"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
| <select id="__specs__" class="ui dropdown width81" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||
| </div> | |||
| <div class="inline required unite min_title field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||
| @@ -287,6 +290,7 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let url_href = location.pathname.split('/create_version')[0] | |||
| @@ -427,53 +431,7 @@ | |||
| $('select.dropdown') | |||
| .dropdown(); | |||
| $('.ui.form') | |||
| .form({ | |||
| on: 'blur', | |||
| inline:true, | |||
| fields: { | |||
| boot_file: { | |||
| identifier : 'boot_file', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/.+\.py$/g]', | |||
| prompt : '启动文件必须为.py结尾' | |||
| } | |||
| ] | |||
| }, | |||
| job_name:{ | |||
| identifier : 'job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||
| prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||
| } | |||
| ] | |||
| }, | |||
| display_job_name:{ | |||
| identifier : 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||
| prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||
| } | |||
| ] | |||
| }, | |||
| attachment:{ | |||
| identifier : 'attachment', | |||
| rules: [ | |||
| { | |||
| type: 'empty', | |||
| prompt : '选择一个数据集' | |||
| } | |||
| ] | |||
| }, | |||
| }, | |||
| }) | |||
| var isValidate = false; | |||
| function validate(){ | |||
| $('.ui.form') | |||
| .form({ | |||
| @@ -517,12 +475,18 @@ | |||
| ] | |||
| }, | |||
| spec_id: { | |||
| identifier: 'spec_id', | |||
| rules: [{ type: 'empty' }] | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function(e){ | |||
| isValidate = false; | |||
| return false; | |||
| } | |||
| }) | |||
| @@ -553,9 +517,22 @@ | |||
| } | |||
| validate() | |||
| $('.ui.create_train_job.green.button').click(function(e) { | |||
| get_name() | |||
| send_run_para() | |||
| validate() | |||
| }) | |||
| ;(function() { | |||
| var SPECS = {{ .Specs }}; | |||
| var showPoint = true; | |||
| renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -1,5 +1,6 @@ | |||
| {{template "base/head" .}} | |||
| <!-- 提示框 --> | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <div class="alert"></div> | |||
| <div class="explore users"> | |||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" | |||
| @@ -159,11 +160,17 @@ | |||
| </div> | |||
| <!-- XPU类型 --> | |||
| <div class="one wide column text center nowrap" style="width:10% !important;"> | |||
| <span style="font-size: 12px;" title="{{.CardType}}"> | |||
| {{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||
| </span> | |||
| </div> | |||
| <span style="font-size: 12px;" title="" class="card_type_{{.DisplayJobName}}_{{$JobID}}"></span> | |||
| </div> | |||
| <script> | |||
| (function(){ | |||
| var spec = {{.Spec}} || {}; | |||
| var cardType = getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType) || '--'; | |||
| var spanEl = document.querySelector('.card_type_{{.DisplayJobName}}_{{$JobID}}'); | |||
| spanEl.setAttribute('title', cardType); | |||
| spanEl.innerText = cardType; | |||
| })(); | |||
| </script> | |||
| <!-- 项目 --> | |||
| <div class="two wide column text center nowrap" style="width: 11%!important;"> | |||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | |||
| @@ -0,0 +1,31 @@ | |||
| window.ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'ASCEND910', v: 'Ascend 910' }, { k: 'MLU270', v: 'MLU270' }, { k: 'RTX3080', v: 'RTX3080' }]; | |||
| window.getListValueWithKey = (list, key, k = 'k', v = 'v', defaultV = '') => { | |||
| for (let i = 0, iLen = list.length; i < iLen; i++) { | |||
| const listI = list[i]; | |||
| if (listI[k] === key) return listI[v]; | |||
| } | |||
| return defaultV; | |||
| }; | |||
| window.renderSpecStr = (spec, showPoint, langObj) => { | |||
| showPoint = false; | |||
| var ngpu = `${spec.ComputeResource}: ${spec.AccCardsNum + '*' + getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType)}`; | |||
| var gpuMemStr = spec.GPUMemGiB != 0 ? `${langObj.gpu_memory}: ${spec.GPUMemGiB}GB, ` : ''; | |||
| var sharedMemStr = spec.ShareMemGiB != 0 ? `, ${langObj.shared_memory}: ${spec.ShareMemGiB}GB` : ''; | |||
| var pointStr = showPoint ? `, ${spec.UnitPrice == 0 ? langObj.free : spec.UnitPrice + langObj.point_hr}` : ''; | |||
| var specStr = `${ngpu}, CPU: ${spec.CpuCores}, ${gpuMemStr}${langObj.memory}: ${spec.MemGiB}GB${sharedMemStr}${pointStr}`; | |||
| return specStr; | |||
| }; | |||
| window.renderSpecsSelect = (specsSel, data, showPoint, langObj) => { | |||
| specsSel.empty(); | |||
| data = data || []; | |||
| var oValue = specsSel.attr('ovalue'); | |||
| for (var i = 0, iLen = data.length; i < iLen; i++) { | |||
| var spec = data[i]; | |||
| var specStr = window.renderSpecStr(spec, showPoint, langObj); | |||
| specsSel.append(`<option name="spec_id" value="${spec.ID}" queueCode="${spec.QueueCode}">${specStr}</option>`); | |||
| } | |||
| oValue && specsSel.val(oValue); | |||
| } | |||
| @@ -10,7 +10,7 @@ export const JOB_TYPE = [{ k: 'DEBUG', v: i18n.t('debugTask') }, { k: 'TRAIN', v | |||
| // 资源管理 | |||
| export const CLUSTERS = [{ k: 'OpenI', v: i18n.t('resourcesManagement.OpenI') }, { k: 'C2Net', v: i18n.t('resourcesManagement.C2Net') }]; | |||
| export const AI_CENTER = [{ k: 'OpenIOne', v: i18n.t('resourcesManagement.OpenIOne') }, { k: 'OpenITwo', v: i18n.t('resourcesManagement.OpenITwo') }, { k: 'chendu', v: i18n.t('resourcesManagement.chenduCenter') }, { k: 'pclcci', v: i18n.t('resourcesManagement.pclcci') }, { k: 'hefei', v: i18n.t('resourcesManagement.hefeiCenter') }, { k: 'xuchang', v: i18n.t('resourcesManagement.xuchangCenter') }]; | |||
| export const AI_CENTER = [{ k: 'OpenIOne', v: i18n.t('resourcesManagement.OpenIOne') }, { k: 'OpenITwo', v: i18n.t('resourcesManagement.OpenITwo') }, { k: 'OpenIChengdu', v: i18n.t('resourcesManagement.OpenIChengdu') }, { k: 'pclcci', v: i18n.t('resourcesManagement.pclcci') }, { k: 'hefei', v: i18n.t('resourcesManagement.hefeiCenter') }, { k: 'xuchang', v: i18n.t('resourcesManagement.xuchangCenter') }]; | |||
| export const COMPUTER_RESOURCES = [{ k: 'GPU', v: 'GPU' }, { k: 'NPU', v: 'NPU' }, { k: 'MLU', v: 'MLU' }]; | |||
| export const ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'ASCEND910', v: 'Ascend 910' }, { k: 'MLU270', v: 'MLU270' }, { k: 'RTX3080', v: 'RTX3080' }]; | |||
| export const SPECIFICATION_STATUS = [{ k: '1', v: i18n.t('resourcesManagement.willOnShelf') }, { k: '2', v: i18n.t('resourcesManagement.onShelf') }, { k: '3', v: i18n.t('resourcesManagement.offShelf') }]; | |||
| @@ -82,7 +82,8 @@ const en = { | |||
| C2Net: 'C2Net', | |||
| OpenIOne: 'OpenI One', | |||
| OpenITwo: 'OpenI Two', | |||
| chenduCenter: 'ChenDu AI Center', | |||
| OpenIChengdu: 'OpenI ChengDu AI Chenter', | |||
| chengduCenter: 'ChengDu AI Center', | |||
| pclcci: 'PCL Cloud Computer Institute', | |||
| hefeiCenter: 'HeFei AI Center', | |||
| xuchangCenter: 'XuChang AI Center', | |||
| @@ -131,6 +132,7 @@ const en = { | |||
| onShelfConfirm: 'Are you sure to on shelf the resources specification?', | |||
| offShelfConfirm: 'Are you sure to off shelf the resources specification?', | |||
| onShelfCode1001: 'On shelf failed, the resources queues not available.', | |||
| onShelfCode1003: 'On shelf failed, the resources specification not available.', | |||
| offShelfDlgTip1: 'The resources specification has already used in scene:', | |||
| offShelfDlgTip2: 'Please confirm to off shelf?', | |||
| resSceneManagement: 'Resources Scene Management', | |||
| @@ -149,7 +151,11 @@ const en = { | |||
| computeCluster: 'Compute Cluster', | |||
| resourceSpecification: 'Resource Specification', | |||
| lastUpdateTime: 'Last Update Time', | |||
| resSceneDeleteConfirm: 'Are you sure to delete the current Resource Scene?', | |||
| resSceneDeleteConfirm: 'Are you sure to delete the current Resource Scene?', | |||
| resourceSpecificationIsAvailable: 'Specification Is Available', | |||
| resourceSpecificationIsAvailableAll: 'Specification Is Available(All)', | |||
| available: 'Available', | |||
| notAvailable: 'Not Available', | |||
| }, | |||
| } | |||
| @@ -82,7 +82,8 @@ const zh = { | |||
| C2Net: '智算集群', | |||
| OpenIOne: '云脑一', | |||
| OpenITwo: '云脑二', | |||
| chenduCenter: '成都人工智能计算中心', | |||
| OpenIChengdu: '启智成都智算', | |||
| chengduCenter: '成都智算', | |||
| pclcci: '鹏城云计算所', | |||
| hefeiCenter: '合肥类脑类脑智能开放平台', | |||
| xuchangCenter: '中原人工智能计算中心', | |||
| @@ -131,6 +132,7 @@ const zh = { | |||
| onShelfConfirm: '请确认上架该规格?', | |||
| offShelfConfirm: '请确认下架该规格?', | |||
| onShelfCode1001: '上架失败,资源池(队列)不可用。', | |||
| onShelfCode1003: '上架失败,资源规格不可用。', | |||
| offShelfDlgTip1: '当前资源规格已在以下场景中使用:', | |||
| offShelfDlgTip2: '请确认进行下架操作?', | |||
| resSceneManagement: '算力资源应用场景管理', | |||
| @@ -150,6 +152,10 @@ const zh = { | |||
| resourceSpecification: '资源规格', | |||
| lastUpdateTime: '最后更新时间', | |||
| resSceneDeleteConfirm: '是否确认删除当前应用场景?', | |||
| resourceSpecificationIsAvailable: '资源规格是否可用', | |||
| resourceSpecificationIsAvailableAll: '资源规格是否可用(全部)', | |||
| available: '可用', | |||
| notAvailable: '不可用', | |||
| }, | |||
| } | |||
| @@ -10,7 +10,8 @@ | |||
| <span>{{ $t('resourcesManagement.resQueueName') }}</span> | |||
| </div> | |||
| <div class="content"> | |||
| <el-input v-model="dataInfo.QueueCode" placeholder="" :disabled="type === 'edit'" maxlength="255"></el-input> | |||
| <el-input v-model="dataInfo.QueueCode" placeholder="" :disabled="type === 'edit'" maxlength="255"> | |||
| </el-input> | |||
| </div> | |||
| </div> | |||
| <div class="form-row"> | |||
| @@ -101,7 +102,7 @@ export default { | |||
| return { | |||
| dialogShow: false, | |||
| clusterList: [CLUSTERS[0]], | |||
| computingCenterList: [AI_CENTER[0], AI_CENTER[1]], | |||
| computingCenterList: [AI_CENTER[0], AI_CENTER[1], AI_CENTER[2]], | |||
| computingTypeList: [...COMPUTER_RESOURCES], | |||
| cardTypeList: [...ACC_CARD_TYPE], | |||
| @@ -88,7 +88,7 @@ | |||
| <script> | |||
| import BaseDialog from '~/components/BaseDialog.vue'; | |||
| import { getResQueueCode, getResSpecificationList, addResScene, updateResScene } from '~/apis/modules/resources'; | |||
| import { JOB_TYPE, CLUSTERS, AI_CENTER, ACC_CARD_TYPE, SPECIFICATION_STATUS } from '~/const'; | |||
| import { JOB_TYPE, CLUSTERS, ACC_CARD_TYPE, SPECIFICATION_STATUS } from '~/const'; | |||
| import { getListValueWithKey } from '~/utils'; | |||
| export default { | |||
| @@ -20,8 +20,8 @@ | |||
| <span>{{ $t('resourcesManagement.sourceSpecCode') }}</span> | |||
| </div> | |||
| <div class="content"> | |||
| <el-input v-model="dataInfo.SourceSpecId" :placeholder="$t('resourcesManagement.sourceSpecCodeTips')" maxlength="255" | |||
| :disabled="type === 'edit'"> | |||
| <el-input v-model="dataInfo.SourceSpecId" :placeholder="$t('resourcesManagement.sourceSpecCodeTips')" | |||
| maxlength="255" :disabled="type === 'edit'"> | |||
| </el-input> | |||
| </div> | |||
| </div> | |||
| @@ -245,6 +245,11 @@ export default { | |||
| type: 'info', | |||
| message: this.$t('resourcesManagement.onShelfCode1001') | |||
| }); | |||
| } else if (action === 'on-shelf' && res.Code === 1003) { | |||
| this.$message({ | |||
| type: 'info', | |||
| message: this.$t('resourcesManagement.onShelfCode1003') | |||
| }); | |||
| } else { | |||
| this.$message({ | |||
| type: 'error', | |||
| @@ -9,6 +9,9 @@ | |||
| <el-select class="select" size="medium" v-model="selStatus" @change="selectChange"> | |||
| <el-option v-for="item in statusList" :key="item.k" :label="item.v" :value="item.k" /> | |||
| </el-select> | |||
| <el-select class="select" size="medium" v-model="selAvailable" @change="selectChange"> | |||
| <el-option v-for="item in availableList" :key="item.k" :label="item.v" :value="item.k" /> | |||
| </el-select> | |||
| </div> | |||
| <div> | |||
| <el-button size="medium" icon="el-icon-refresh" @click="syncComputerNetwork" v-loading="syncLoading"> | |||
| @@ -19,7 +22,7 @@ | |||
| </div> | |||
| <div class="table-container"> | |||
| <div style="min-height:600px;"> | |||
| <el-table border :data="tableData" style="width: 100%" v-loading="loading" stripe> | |||
| <el-table border :data="tableData" style="width: 100%;min-width:1700px;" v-loading="loading" stripe> | |||
| <el-table-column prop="ID" label="ID" align="center" header-align="center" width="60"></el-table-column> | |||
| <el-table-column prop="SpecStr" :label="$t('resourcesManagement.resourceSpecification')" align="left" | |||
| header-align="center" min-width="160"> | |||
| @@ -49,6 +52,14 @@ | |||
| <span style="font-weight:600;font-size:14px;">{{ scope.row.UnitPrice }}</span> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column prop="IsAvailableStr" :label="$t('resourcesManagement.resourceSpecificationIsAvailable')" align="center" | |||
| header-align="center" width="100"> | |||
| <template slot-scope="scope"> | |||
| <span :style="{ color: scope.row.IsAvailable ? 'rgb(82, 196, 26)' : 'rgb(245, 34, 45)' }">{{ | |||
| scope.row.IsAvailableStr | |||
| }}</span> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column prop="StatusStr" :label="$t('resourcesManagement.status')" align="center" | |||
| header-align="center" width="100"> | |||
| <template slot-scope="scope"> | |||
| @@ -60,7 +71,10 @@ | |||
| <el-table-column :label="$t('operation')" align="center" header-align="center" width="100"> | |||
| <template slot-scope="scope"> | |||
| <span v-if="scope.row.Status == '1' && !scope.row.UnitPrice"> | |||
| <span class="op-btn" @click="showDialog('edit', scope.row)">{{ | |||
| <span v-if="scope.row.IsAvailable" class="op-btn" @click="showDialog('edit', scope.row)">{{ | |||
| $t('resourcesManagement.toSetPriceAndOnShelf') | |||
| }}</span> | |||
| <span v-else class="op-btn" style="color: rgb(187, 187, 187); cursor: not-allowed;">{{ | |||
| $t('resourcesManagement.toSetPriceAndOnShelf') | |||
| }}</span> | |||
| </span> | |||
| @@ -71,9 +85,12 @@ | |||
| }}</span> | |||
| </span> | |||
| <span v-if="scope.row.Status == '3' || scope.row.Status == '1' && scope.row.UnitPrice"> | |||
| <span class="op-btn" @click="onShelf(scope.row)">{{ | |||
| <span v-if="scope.row.IsAvailable" class="op-btn" @click="onShelf(scope.row)">{{ | |||
| $t('resourcesManagement.toOnShelf') | |||
| }}</span> | |||
| <span v-else class="op-btn" style="color: rgb(187, 187, 187); cursor: not-allowed;">{{ | |||
| $t('resourcesManagement.toSetPriceAndOnShelf') | |||
| }}</span> | |||
| </span> | |||
| </template> | |||
| </el-table-column> | |||
| @@ -132,6 +149,8 @@ export default { | |||
| queueList: [{ k: '', v: this.$t('resourcesManagement.allResQueue') }], | |||
| selStatus: '', | |||
| statusList: [{ k: '', v: this.$t('resourcesManagement.allStatus') }, ...SPECIFICATION_STATUS], | |||
| selAvailable: '', | |||
| availableList: [{ k: '', v: this.$t('resourcesManagement.resourceSpecificationIsAvailableAll') }, { k: '1', v: this.$t('resourcesManagement.available') }, { k: '2', v: this.$t('resourcesManagement.notAvailable') }], | |||
| clusterList: [...CLUSTERS], | |||
| accCardTypeList: [...ACC_CARD_TYPE], | |||
| syncLoading: false, | |||
| @@ -178,6 +197,7 @@ export default { | |||
| const params = { | |||
| queue: this.selQueue, | |||
| status: this.selStatus, | |||
| available: this.selAvailable, | |||
| page: this.pageInfo.curpage, | |||
| pagesize: this.pageInfo.pageSize, | |||
| }; | |||
| @@ -201,6 +221,8 @@ export default { | |||
| UpdatedTimeStr: formatDate(new Date(Spec.UpdatedTime * 1000), 'yyyy-MM-dd HH:mm:ss'), | |||
| Status: Spec.Status.toString(), | |||
| StatusStr: getListValueWithKey(this.statusList, Spec.Status.toString()), | |||
| IsAvailable: Spec.IsAvailable, | |||
| IsAvailableStr: Spec.IsAvailable ? this.$t('resourcesManagement.available') : this.$t('resourcesManagement.notAvailable'), | |||
| } | |||
| }); | |||
| this.tableData = data; | |||
| @@ -280,6 +302,11 @@ export default { | |||
| type: 'info', | |||
| message: this.$t('resourcesManagement.onShelfCode1001') | |||
| }); | |||
| } else if (type === 'on-shelf' && res.Code === 1003) { | |||
| this.$message({ | |||
| type: 'info', | |||
| message: this.$t('resourcesManagement.onShelfCode1003') | |||
| }); | |||
| } else { | |||
| this.$message({ | |||
| type: 'error', | |||