#2799 资源管理二期

Closed
chenyifan01 wants to merge 45 commits from res-manage-v2 into V20220830
  1. +33
    -2
      models/cloudbrain.go
  2. +109
    -0
      models/cloudbrain_spec.go
  3. +1
    -0
      models/models.go
  4. +280
    -5
      models/resource_specification.go
  5. +2
    -0
      modules/auth/cloudbrain.go
  6. +1
    -2
      modules/auth/grampus.go
  7. +3
    -0
      modules/auth/modelarts.go
  8. +15
    -73
      modules/cloudbrain/cloudbrain.go
  9. +7
    -9
      modules/grampus/grampus.go
  10. +18
    -13
      modules/modelarts/modelarts.go
  11. +3
    -0
      options/locale/locale_en-US.ini
  12. +3
    -0
      options/locale/locale_zh-CN.ini
  13. +42
    -4
      routers/admin/resources.go
  14. +2
    -0
      routers/private/internal.go
  15. +177
    -268
      routers/repo/cloudbrain.go
  16. +42
    -15
      routers/repo/grampus.go
  17. +99
    -89
      routers/repo/modelarts.go
  18. +1
    -0
      routers/response/response_list.go
  19. +458
    -1
      services/cloudbrain/resource/resource_specification.go
  20. +25
    -0
      templates/custom/task_wait_count.tmpl
  21. +42
    -9
      templates/repo/cloudbrain/benchmark/new.tmpl
  22. +20
    -4
      templates/repo/cloudbrain/benchmark/show.tmpl
  23. +29
    -11
      templates/repo/cloudbrain/inference/new.tmpl
  24. +16
    -2
      templates/repo/cloudbrain/inference/show.tmpl
  25. +31
    -8
      templates/repo/cloudbrain/new.tmpl
  26. +17
    -6
      templates/repo/cloudbrain/show.tmpl
  27. +36
    -13
      templates/repo/cloudbrain/trainjob/new.tmpl
  28. +16
    -2
      templates/repo/cloudbrain/trainjob/show.tmpl
  29. +38
    -17
      templates/repo/grampus/trainjob/gpu/new.tmpl
  30. +31
    -10
      templates/repo/grampus/trainjob/npu/new.tmpl
  31. +14
    -2
      templates/repo/grampus/trainjob/show.tmpl
  32. +27
    -8
      templates/repo/modelarts/inferencejob/new.tmpl
  33. +15
    -2
      templates/repo/modelarts/inferencejob/show.tmpl
  34. +22
    -3
      templates/repo/modelarts/notebook/new.tmpl
  35. +23
    -8
      templates/repo/modelarts/notebook/show.tmpl
  36. +28
    -9
      templates/repo/modelarts/trainjob/new.tmpl
  37. +18
    -1
      templates/repo/modelarts/trainjob/show.tmpl
  38. +61
    -6
      templates/repo/modelarts/trainjob/version_new.tmpl
  39. +29
    -0
      web_src/js/standalone/specsuse.js

+ 33
- 2
models/cloudbrain.go View File

@@ -119,6 +119,10 @@ const (
//AI center
AICenterOfCloudBrainOne = "OpenIOne"
AICenterOfCloudBrainTwo = "OpenITwo"

//ComputeResource
GPU = "GPU"
NPU = "NPU"
)

type Cloudbrain struct {
@@ -189,6 +193,7 @@ type Cloudbrain struct {
BenchmarkTypeRankLink string `xorm:"-"`
StartTime timeutil.TimeStamp
EndTime timeutil.TimeStamp
Spec *Specification `xorm:"-"`
}

func (task *Cloudbrain) ComputeAndSetDuration() {
@@ -1718,11 +1723,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
}
@@ -2001,11 +2019,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
}
@@ -2397,6 +2422,12 @@ 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


+ 109
- 0
models/cloudbrain_spec.go View File

@@ -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
}

+ 1
- 0
models/models.go View File

@@ -150,6 +150,7 @@ func init() {
new(ResourceScene),
new(ResourceSceneSpec),
new(AdminOperateLog),
new(CloudbrainSpec),
new(CloudbrainTemp),
new(DatasetReference),
)


+ 280
- 5
models/resource_specification.go View File

@@ -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,220 @@ 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").
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(&param)
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,
}
_, 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
}

+ 2
- 0
modules/auth/cloudbrain.go View File

@@ -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 {


+ 1
- 2
modules/auth/grampus.go View File

@@ -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 {


+ 3
- 0
modules/auth/modelarts.go View File

@@ -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 {


+ 15
- 73
modules/cloudbrain/cloudbrain.go View File

@@ -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)


+ 7
- 9
modules/grampus/grampus.go View File

@@ -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 {


+ 18
- 13
modules/modelarts/modelarts.go View File

@@ -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
}

@@ -257,7 +258,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)
}
@@ -271,7 +272,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,
@@ -308,7 +309,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,
@@ -318,6 +319,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
Description: description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
}

err = models.CreateCloudbrain(task)
@@ -348,7 +350,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,
@@ -370,7 +372,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,
},
@@ -419,7 +421,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,
@@ -428,6 +430,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
TotalVersionCount: req.TotalVersionCount,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: req.Spec,
})

if createErr != nil {
@@ -479,7 +482,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,
@@ -500,7 +503,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,
@@ -567,7 +570,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,
@@ -576,6 +579,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())
@@ -666,7 +670,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,
},
@@ -718,7 +722,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,
@@ -734,6 +738,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e
ResultUrl: req.ResultUrl,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: req.Spec,
})

if err != nil {


+ 3
- 0
options/locale/locale_en-US.ini View File

@@ -3201,6 +3201,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


+ 3
- 0
options/locale/locale_zh-CN.ini View File

@@ -3219,6 +3219,9 @@ gpu_num = GPU数
cpu_num = CPU数
memory = 内存
shared_memory = 共享内存
gpu_memory = 显存
free = 免费
point_hr = 积分/时

DEBUG = 调试任务
SNN4IMAGENET = 评测任务


+ 42
- 4
routers/admin/resources.go View File

@@ -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))
}

+ 2
- 0
routers/private/internal.go View File

@@ -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)
}

+ 177
- 268
routers/repo/cloudbrain.go View File

@@ -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)
@@ -2447,7 +2351,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: "",
@@ -2455,8 +2358,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)
@@ -2476,9 +2379,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

@@ -2560,7 +2461,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
}
req := cloudbrain.GenerateCloudBrainTaskReq{
Ctx: ctx,
DisplayJobName: displayJobName,
@@ -2576,7 +2486,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,
@@ -2584,8 +2493,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)


+ 42
- 15
routers/repo/grampus.go View File

@@ -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, false)
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task)


+ 99
- 89
routers/repo/modelarts.go View File

@@ -2,9 +2,9 @@ package repo

import (
"archive/zip"
"code.gitea.io/gitea/services/cloudbrain/resource"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
@@ -140,11 +140,7 @@ func notebookNewDataPrepare(ctx *context.Context) error {
}
ctx.Data["images"] = modelarts.ImageInfos.ImageInfo

if modelarts.FlavorInfos == nil {
json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos)
}
ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo
setSpecBySpecialPoolConfig(ctx, string(models.JobTypeDebug))
prepareCloudbrainTwoDebugSpecs(ctx)

ctx.Data["datasetType"] = models.TypeCloudBrainTwo

@@ -154,6 +150,16 @@ func notebookNewDataPrepare(ctx *context.Context) error {
return nil
}

func prepareCloudbrainTwoDebugSpecs(ctx *context.Context) {
noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{
JobType: models.JobTypeDebug,
ComputeResource: models.NPU,
Cluster: models.OpenICluster,
AiCenterCode: models.AICenterOfCloudBrainTwo,
})
ctx.Data["Specs"] = noteBookSpecs
}

func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) {
ctx.Data["PageIsNotebook"] = true
jobName := form.JobName
@@ -204,7 +210,6 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
uuid := form.Attachment
description := form.Description
flavor := form.Flavor
imageId := form.ImageId
repo := ctx.Repo.Repository

@@ -240,14 +245,17 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
}
}

errStr := checkModelArtsSpecialPool(ctx, flavor, string(models.JobTypeDebug))
if errStr != "" {
spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{
JobType: models.JobTypeDebug,
ComputeResource: models.NPU,
Cluster: models.OpenICluster,
AiCenterCode: models.AICenterOfCloudBrainTwo})
if err != nil || spec == nil {
notebookNewDataPrepare(ctx)
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsNotebookNew, &form)
ctx.RenderWithErr("Resource specification not available", tplModelArtsNotebookNew, &form)
return
}

err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, flavor, imageId)
err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec)
if err != nil {
log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"])
notebookNewDataPrepare(ctx)
@@ -292,24 +300,7 @@ func NotebookShow(ctx *context.Context) {
if err == nil {
task.User = user
}
if modelarts.FlavorInfos == nil {
json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos)
}

findSpec := false
if modelarts.FlavorInfos != nil {
ctx.Data["resource_spec"] = modelarts.FlavorInfos.FlavorInfo[0].Desc
for _, f := range modelarts.FlavorInfos.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
@@ -421,6 +412,7 @@ func NotebookRestart(ctx *context.Context) {
var resultCode = "-1"
var errorMsg = ""
var status = ""
var spec *models.Specification

task := ctx.Cloudbrain

@@ -448,6 +440,23 @@ 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
}
spec, err = resource.GetAndCheckSpec(ctx.User.ID, oldSpec.ID, models.FindSpecsOptions{
JobType: models.JobType(task.JobType),
ComputeResource: models.NPU,
Cluster: models.OpenICluster,
AiCenterCode: models.AICenterOfCloudBrainTwo})
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,
@@ -491,8 +500,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)
@@ -725,14 +733,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
@@ -750,6 +751,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 setSpecBySpecialPoolConfig(ctx *context.Context, jobType string) {
modelarts.InitSpecialPool()

@@ -832,13 +843,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 {
@@ -926,14 +931,7 @@ 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
}
ctx.Data["flavor_infos"] = flavorInfos.Info

setSpecBySpecialPoolConfig(ctx, string(models.JobTypeTrain))
prepareCloudbrainTwoTrainSpecs(ctx)

var Parameters modelarts.Parameters
if err = json.Unmarshal([]byte(task.Parameters), &Parameters); err != nil {
@@ -1021,13 +1019,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 {
@@ -1080,7 +1072,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
@@ -1126,10 +1117,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
@@ -1292,7 +1287,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,
@@ -1308,6 +1302,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
@@ -1393,7 +1388,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
@@ -1431,10 +1425,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
}

@@ -1588,7 +1586,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),
@@ -1605,6 +1602,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
@@ -1792,7 +1790,6 @@ func TrainJobShow(ctx *context.Context) {
for i, task := range VersionListTasks {

var parameters models.Parameters

err := json.Unmarshal([]byte(VersionListTasks[i].Parameters), &parameters)
if err != nil {
log.Error("Failed to Unmarshal Parameters: %s (%v)", VersionListTasks[i].Parameters, err)
@@ -1813,6 +1810,14 @@ func TrainJobShow(ctx *context.Context) {
datasetList = append(datasetList, GetCloudBrainDataSetInfo(task.Uuid, 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)
@@ -1980,7 +1985,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
@@ -2050,13 +2054,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 {
@@ -2108,7 +2115,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
@@ -2164,7 +2171,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,
@@ -2184,6 +2190,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference
ModelVersion: modelVersion,
CkptName: ckptName,
ResultUrl: resultObsPath,
Spec: spec,
DatasetName: datasetNames,
}

@@ -2364,14 +2371,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
@@ -2402,6 +2402,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

@@ -2518,7 +2528,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


+ 1
- 0
routers/response/response_list.go View File

@@ -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"}

+ 458
- 1
services/cloudbrain/resource/resource_specification.go View File

@@ -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,449 @@ 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] = ""
}
}
}
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
}

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
}

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: float32(specConfig.ShareMemMiB) / 1024,
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,
})
}

+ 25
- 0
templates/custom/task_wait_count.tmpl View File

@@ -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>

+ 42
- 9
templates/repo/cloudbrain/benchmark/new.tmpl View File

@@ -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>&nbsp;
@@ -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'
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;">&nbsp;
<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'
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
@@ -342,4 +363,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>

+ 20
- 4
templates/repo/cloudbrain/benchmark/show.tmpl View File

@@ -453,7 +453,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>
@@ -464,9 +464,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>
@@ -571,7 +571,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()

@@ -606,4 +621,5 @@
});
}

</script>

+ 29
- 11
templates/repo/cloudbrain/inference/new.tmpl View File

@@ -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"}}" 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&&params.parameter.forEach((item,index)=>{
Add_parameter(index,flag=true,item)
})
})
// 参数增加、删除、修改、保存
function Add_parameter(i,flag=false,paramsObject={}) {
@@ -509,4 +516,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>

+ 16
- 2
templates/repo/cloudbrain/inference/show.tmpl View File

@@ -340,7 +340,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>
@@ -482,7 +482,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>
@@ -555,6 +555,7 @@

</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>

<script>
$('.menu .item').tab()
@@ -615,4 +616,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>

+ 31
- 8
templates/repo/cloudbrain/new.tmpl View File

@@ -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'
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')
@@ -289,4 +301,15 @@
})

;(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>

+ 17
- 6
templates/repo/cloudbrain/show.tmpl View File

@@ -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">
@@ -554,7 +552,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 () {
@@ -595,4 +593,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>

+ 36
- 13
templates/repo/cloudbrain/trainjob/new.tmpl View File

@@ -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"}}"
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&&params.parameter.forEach((item,index)=>{
Add_parameter(index,flag=true,item)
})
})
// 参数增加、删除、修改、保存
function Add_parameter(i,flag=false,paramsObject={}) {
@@ -419,6 +431,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>

+ 16
- 2
templates/repo/cloudbrain/trainjob/show.tmpl View File

@@ -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>
@@ -671,6 +671,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 = {
@@ -981,4 +982,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>

+ 38
- 17
templates/repo/grampus/trainjob/gpu/new.tmpl View File

@@ -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"></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&&params.parameter.forEach((item,index)=>{
Add_parameter(index,flag=true,item)
})
})
// 参数增加、删除、修改、保存
function Add_parameter(i,flag=false,paramsObject={}) {
@@ -339,7 +348,7 @@
// $('.ui.page.dimmer').dimmer('show')
document.getElementById("mask").style.display = "block"
},
onFailure: function(e){
onFailure: function(e){
return false;
}
})
@@ -374,4 +383,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>

+ 31
- 10
templates/repo/grampus/trainjob/npu/new.tmpl View File

@@ -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"></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&&params.parameter.forEach((item,index)=>{
Add_parameter(index,flag=true,item)
})
})
// 参数增加、删除、修改、保存
function Add_parameter(i,flag=false,paramsObject={}) {
@@ -309,7 +318,7 @@
$(this).popup('show')
});

$('select.dropdown')
.dropdown();

@@ -395,4 +404,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>

+ 14
- 2
templates/repo/grampus/trainjob/show.tmpl View File

@@ -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>
@@ -629,8 +629,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,


+ 27
- 8
templates/repo/modelarts/inferencejob/new.tmpl View File

@@ -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"></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'))
@@ -532,4 +539,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>

+ 15
- 2
templates/repo/modelarts/inferencejob/show.tmpl View File

@@ -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>
@@ -515,6 +515,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(){
@@ -531,5 +532,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>

+ 22
- 3
templates/repo/modelarts/notebook/new.tmpl View File

@@ -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"></select>
</div>
<!--<div class="inline required field">
<label>数据集存放路径</label>
@@ -95,7 +102,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');
@@ -171,4 +178,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>

+ 23
- 8
templates/repo/modelarts/notebook/show.tmpl View File

@@ -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;"><a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a></td>
<td style="word-wrap: break-word;word-break: break-all;">{{.DatasetDownloadLink}}</td>
@@ -481,7 +481,7 @@

</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
$('.menu .item').tab()

@@ -491,4 +491,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>

+ 28
- 9
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -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"></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>
@@ -310,7 +317,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
@@ -327,7 +334,7 @@
.tab();
$(document).keydown(function(event){
switch(event.keyCode){
case 13:return false;
case 13:return false;
}
});
// 参数增加、删除、修改、保存
@@ -523,4 +530,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>

+ 18
- 1
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -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>


+ 61
- 6
templates/repo/modelarts/trainjob/version_new.tmpl View File

@@ -72,13 +72,50 @@
{{end}}
<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}}">
{{template "custom/wait_count_train" Dict "ctx" $}}
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;">
<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>
<div class="ui blue mini menu compact selectcloudbrain">
<a class="active item" href="javascript:void 0;" style="cursor:not-allowed;">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}}
</a>
<a class="item" href="javascript:void 0;" style="cursor:not-allowed;background:rgba(0,0,0,.03);">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta)
</a>
</div>
</div>
<div class="required inline min_title field">
<label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue mini menu compact selectcloudbrain">
<a class="item" href="javascript:void 0;" style="cursor:not-allowed;background:rgba(0,0,0,.03);">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16"
height="16">
<path fill="none" d="M0 0h24v24H0z" />
<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>
CPU/GPU
</a>
<a class="active item" href="javascript:void 0;" style="cursor:not-allowed;">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16"
height="16">
<path fill="none" d="M0 0h24v24H0z" />
<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>
</div>
<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: 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>
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input type="hidden" style="width: 60%;" name="job_name" id="job_name" value="{{.job_name}}">
@@ -211,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}}
@@ -223,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"></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>
@@ -249,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]
@@ -514,10 +556,23 @@
$("input#ai_flaver_name").val(name2)

}

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>

+ 29
- 0
web_src/js/standalone/specsuse.js View File

@@ -0,0 +1,29 @@
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 || [];
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>`);
}
}

Loading…
Cancel
Save