Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/2875tags/v1.22.9.1
@@ -25,7 +25,8 @@ type ModelArtsJobStatus string | |||||
const ( | const ( | ||||
TypeCloudBrainOne int = iota | TypeCloudBrainOne int = iota | ||||
TypeCloudBrainTwo | TypeCloudBrainTwo | ||||
TypeC2Net //智算网络 | |||||
TypeC2Net //智算网络 | |||||
TypeCDCenter //成都智算中心 | |||||
TypeCloudBrainAll = -1 | TypeCloudBrainAll = -1 | ||||
) | ) | ||||
@@ -120,6 +121,11 @@ const ( | |||||
//AI center | //AI center | ||||
AICenterOfCloudBrainOne = "OpenIOne" | AICenterOfCloudBrainOne = "OpenIOne" | ||||
AICenterOfCloudBrainTwo = "OpenITwo" | AICenterOfCloudBrainTwo = "OpenITwo" | ||||
AICenterOfChengdu = "OpenIChengdu" | |||||
//ComputeResource | |||||
GPU = "GPU" | |||||
NPU = "NPU" | |||||
) | ) | ||||
type Cloudbrain struct { | type Cloudbrain struct { | ||||
@@ -190,6 +196,7 @@ type Cloudbrain struct { | |||||
BenchmarkTypeRankLink string `xorm:"-"` | BenchmarkTypeRankLink string `xorm:"-"` | ||||
StartTime timeutil.TimeStamp | StartTime timeutil.TimeStamp | ||||
EndTime timeutil.TimeStamp | EndTime timeutil.TimeStamp | ||||
Spec *Specification `xorm:"-"` | |||||
} | } | ||||
func (task *Cloudbrain) ComputeAndSetDuration() { | func (task *Cloudbrain) ComputeAndSetDuration() { | ||||
@@ -596,37 +603,17 @@ type ResourceSpec struct { | |||||
ShareMemMiB int `json:"shareMemMiB"` | ShareMemMiB int `json:"shareMemMiB"` | ||||
} | } | ||||
type FlavorInfos struct { | |||||
FlavorInfo []*FlavorInfo `json:"flavor_info"` | |||||
} | |||||
type FlavorInfo struct { | |||||
Id int `json:"id"` | |||||
Value string `json:"value"` | |||||
Desc string `json:"desc"` | |||||
} | |||||
type SpecialPools struct { | type SpecialPools struct { | ||||
Pools []*SpecialPool `json:"pools"` | Pools []*SpecialPool `json:"pools"` | ||||
} | } | ||||
type SpecialPool struct { | type SpecialPool struct { | ||||
Org string `json:"org"` | |||||
Type string `json:"type"` | |||||
IsExclusive bool `json:"isExclusive"` | |||||
Pool []*GpuInfo `json:"pool"` | |||||
JobType []string `json:"jobType"` | |||||
ResourceSpec []*ResourceSpec `json:"resourceSpecs"` | |||||
Flavor []*FlavorInfo `json:"flavor"` | |||||
} | |||||
type ImageInfosModelArts struct { | |||||
ImageInfo []*ImageInfoModelArts `json:"image_info"` | |||||
} | |||||
type ImageInfoModelArts struct { | |||||
Id string `json:"id"` | |||||
Value string `json:"value"` | |||||
Desc string `json:"desc"` | |||||
Org string `json:"org"` | |||||
Type string `json:"type"` | |||||
IsExclusive bool `json:"isExclusive"` | |||||
Pool []*GpuInfo `json:"pool"` | |||||
JobType []string `json:"jobType"` | |||||
ResourceSpec []*ResourceSpec `json:"resourceSpecs"` | |||||
Flavor []*setting.FlavorInfo `json:"flavor"` | |||||
} | } | ||||
type PoolInfos struct { | type PoolInfos struct { | ||||
@@ -732,6 +719,17 @@ type CreateNotebook2Params struct { | |||||
Volume VolumeReq `json:"volume"` | Volume VolumeReq `json:"volume"` | ||||
} | } | ||||
type CreateNotebookWithoutPoolParams struct { | |||||
JobName string `json:"name"` | |||||
Description string `json:"description"` | |||||
Duration int64 `json:"duration"` //ms | |||||
Feature string `json:"feature"` | |||||
Flavor string `json:"flavor"` | |||||
ImageID string `json:"image_id"` | |||||
WorkspaceID string `json:"workspace_id"` | |||||
Volume VolumeReq `json:"volume"` | |||||
} | |||||
type VolumeReq struct { | type VolumeReq struct { | ||||
Capacity int `json:"capacity"` | Capacity int `json:"capacity"` | ||||
Category string `json:"category"` | Category string `json:"category"` | ||||
@@ -955,6 +953,7 @@ type NotebookGetJobTokenResult struct { | |||||
} | } | ||||
type NotebookDelResult struct { | type NotebookDelResult struct { | ||||
NotebookResult | |||||
InstanceID string `json:"instance_id"` | InstanceID string `json:"instance_id"` | ||||
} | } | ||||
@@ -1481,12 +1480,6 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
) | ) | ||||
} | } | ||||
if len(opts.ComputeResource) > 0 { | |||||
cond = cond.And( | |||||
builder.Eq{"cloudbrain.compute_resource": opts.ComputeResource}, | |||||
) | |||||
} | |||||
if len(opts.JobTypes) > 0 { | if len(opts.JobTypes) > 0 { | ||||
if opts.JobTypeNot { | if opts.JobTypeNot { | ||||
cond = cond.And( | cond = cond.And( | ||||
@@ -1506,7 +1499,7 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
if (opts.Cluster) != "" { | if (opts.Cluster) != "" { | ||||
if opts.Cluster == "resource_cluster_openi" { | if opts.Cluster == "resource_cluster_openi" { | ||||
cond = cond.And( | cond = cond.And( | ||||
builder.Or(builder.Eq{"cloudbrain.type": TypeCloudBrainOne}, builder.Eq{"cloudbrain.type": TypeCloudBrainTwo}), | |||||
builder.Or(builder.Eq{"cloudbrain.type": TypeCloudBrainOne}, builder.Eq{"cloudbrain.type": TypeCloudBrainTwo}, builder.Eq{"cloudbrain.type": TypeCDCenter}), | |||||
) | ) | ||||
} | } | ||||
if opts.Cluster == "resource_cluster_c2net" { | if opts.Cluster == "resource_cluster_c2net" { | ||||
@@ -1720,11 +1713,24 @@ func CloudbrainsVersionList(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int, e | |||||
} | } | ||||
func CreateCloudbrain(cloudbrain *Cloudbrain) (err error) { | func CreateCloudbrain(cloudbrain *Cloudbrain) (err error) { | ||||
session := x.NewSession() | |||||
defer session.Close() | |||||
err = session.Begin() | |||||
cloudbrain.TrainJobDuration = DURATION_STR_ZERO | 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 | 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) | go IncreaseDatasetUseCount(cloudbrain.Uuid) | ||||
return nil | return nil | ||||
} | } | ||||
@@ -1959,7 +1965,7 @@ func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTy | |||||
func GetCloudbrainNotebookCountByUserID(userID int64) (int, error) { | func GetCloudbrainNotebookCountByUserID(userID int64) (int, error) { | ||||
count, err := x.In("status", ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting, ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsRestarting). | count, err := x.In("status", ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting, ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsRestarting). | ||||
And("job_type = ? and user_id = ? and type = ?", JobTypeDebug, userID, TypeCloudBrainTwo).Count(new(Cloudbrain)) | |||||
And("job_type = ? and user_id = ? and type in (?,?)", JobTypeDebug, userID, TypeCloudBrainTwo, TypeCDCenter).Count(new(Cloudbrain)) | |||||
return int(count), err | return int(count), err | ||||
} | } | ||||
@@ -2003,11 +2009,18 @@ func RestartCloudbrain(old *Cloudbrain, new *Cloudbrain) (err error) { | |||||
return err | return err | ||||
} | } | ||||
if _, err = sess.NoAutoTime().Insert(new); err != nil { | |||||
if _, err = sess.NoAutoTime().InsertOne(new); err != nil { | |||||
sess.Rollback() | sess.Rollback() | ||||
return err | 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 { | if err = sess.Commit(); err != nil { | ||||
return err | return err | ||||
} | } | ||||
@@ -2399,7 +2412,57 @@ func GetCloudbrainByIDs(ids []int64) ([]*Cloudbrain, error) { | |||||
Find(&cloudbrains) | 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) { | 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)) | count, err := x.Where("job_name = ? and job_type= ? and type = ?", jobName, jobType, typeCloudbrain).Count(new(Cloudbrain)) | ||||
return int(count), err | return int(count), err | ||||
} | } | ||||
func LoadSpecs(tasks []*Cloudbrain) error { | |||||
cloudbrainIds := make([]int64, len(tasks)) | |||||
for i, v := range tasks { | |||||
cloudbrainIds[i] = v.ID | |||||
} | |||||
specs := make([]*CloudbrainSpec, 0) | |||||
err := x.In("cloudbrain_id", cloudbrainIds).Find(&specs) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
specMap := make(map[int64]*CloudbrainSpec) | |||||
for _, v := range specs { | |||||
specMap[v.SpecId] = v | |||||
} | |||||
for _, v := range tasks { | |||||
if specMap[v.ID] != nil { | |||||
v.Spec = specMap[v.ID].ConvertToSpecification() | |||||
} | |||||
} | |||||
return nil | |||||
} | |||||
func LoadSpecs4CloudbrainInfo(tasks []*CloudbrainInfo) error { | |||||
cloudbrainIds := make([]int64, len(tasks)) | |||||
for i, v := range tasks { | |||||
cloudbrainIds[i] = v.Cloudbrain.ID | |||||
} | |||||
specs := make([]*CloudbrainSpec, 0) | |||||
err := x.In("cloudbrain_id", cloudbrainIds).Find(&specs) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
specMap := make(map[int64]*CloudbrainSpec) | |||||
for _, v := range specs { | |||||
specMap[v.CloudbrainID] = v | |||||
} | |||||
for _, v := range tasks { | |||||
if specMap[v.Cloudbrain.ID] != nil { | |||||
v.Cloudbrain.Spec = specMap[v.Cloudbrain.ID].ConvertToSpecification() | |||||
} | |||||
} | |||||
return nil | |||||
} |
@@ -0,0 +1,109 @@ | |||||
package models | |||||
import ( | |||||
"code.gitea.io/gitea/modules/timeutil" | |||||
) | |||||
type CloudbrainSpec struct { | |||||
CloudbrainID int64 `xorm:"pk"` | |||||
SpecId int64 `xorm:"index"` | |||||
SourceSpecId string | |||||
AccCardsNum int | |||||
AccCardType string | |||||
CpuCores int | |||||
MemGiB float32 | |||||
GPUMemGiB float32 | |||||
ShareMemGiB float32 | |||||
ComputeResource string | |||||
UnitPrice int | |||||
QueueId int64 | |||||
QueueCode string | |||||
Cluster string | |||||
AiCenterCode string | |||||
AiCenterName string | |||||
IsExclusive bool | |||||
ExclusiveOrg string | |||||
CreatedTime timeutil.TimeStamp `xorm:"created"` | |||||
UpdatedTime timeutil.TimeStamp `xorm:"updated"` | |||||
} | |||||
func (s CloudbrainSpec) ConvertToSpecification() *Specification { | |||||
return &Specification{ | |||||
ID: s.SpecId, | |||||
SourceSpecId: s.SourceSpecId, | |||||
AccCardsNum: s.AccCardsNum, | |||||
AccCardType: s.AccCardType, | |||||
CpuCores: s.CpuCores, | |||||
MemGiB: s.MemGiB, | |||||
GPUMemGiB: s.GPUMemGiB, | |||||
ShareMemGiB: s.ShareMemGiB, | |||||
ComputeResource: s.ComputeResource, | |||||
UnitPrice: s.UnitPrice, | |||||
QueueId: s.QueueId, | |||||
QueueCode: s.QueueCode, | |||||
Cluster: s.Cluster, | |||||
AiCenterCode: s.AiCenterCode, | |||||
AiCenterName: s.AiCenterName, | |||||
IsExclusive: s.IsExclusive, | |||||
ExclusiveOrg: s.ExclusiveOrg, | |||||
} | |||||
} | |||||
func NewCloudBrainSpec(cloudbrainId int64, s Specification) CloudbrainSpec { | |||||
return CloudbrainSpec{ | |||||
CloudbrainID: cloudbrainId, | |||||
SpecId: s.ID, | |||||
SourceSpecId: s.SourceSpecId, | |||||
AccCardsNum: s.AccCardsNum, | |||||
AccCardType: s.AccCardType, | |||||
CpuCores: s.CpuCores, | |||||
MemGiB: s.MemGiB, | |||||
GPUMemGiB: s.GPUMemGiB, | |||||
ShareMemGiB: s.ShareMemGiB, | |||||
ComputeResource: s.ComputeResource, | |||||
UnitPrice: s.UnitPrice, | |||||
QueueId: s.QueueId, | |||||
QueueCode: s.QueueCode, | |||||
Cluster: s.Cluster, | |||||
AiCenterCode: s.AiCenterCode, | |||||
AiCenterName: s.AiCenterName, | |||||
IsExclusive: s.IsExclusive, | |||||
ExclusiveOrg: s.ExclusiveOrg, | |||||
} | |||||
} | |||||
func InsertCloudbrainSpec(c CloudbrainSpec) (int64, error) { | |||||
return x.Insert(&c) | |||||
} | |||||
func GetCloudbrainSpecByID(cloudbrainId int64) (*CloudbrainSpec, error) { | |||||
r := &CloudbrainSpec{} | |||||
if has, err := x.Where("cloudbrain_id = ?", cloudbrainId).Get(r); err != nil { | |||||
return nil, err | |||||
} else if !has { | |||||
return nil, nil | |||||
} | |||||
return r, nil | |||||
} | |||||
func FindCloudbrainTask(page, pageSize int) ([]*Cloudbrain, error) { | |||||
r := make([]*Cloudbrain, 0) | |||||
err := x.Unscoped(). | |||||
Limit(pageSize, (page-1)*pageSize). | |||||
OrderBy("cloudbrain.id"). | |||||
Find(&r) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return r, nil | |||||
} | |||||
func CountNoSpecHistoricTask() (int64, error) { | |||||
n, err := x.Unscoped(). | |||||
Where(" 1=1 and not exists (select 1 from cloudbrain_spec where cloudbrain.id = cloudbrain_spec.cloudbrain_id)"). | |||||
Count(&Cloudbrain{}) | |||||
if err != nil { | |||||
return 0, err | |||||
} | |||||
return n, nil | |||||
} |
@@ -130,15 +130,11 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions) | |||||
permission = false | permission = false | ||||
datasets[i].Repo.GetOwner() | datasets[i].Repo.GetOwner() | ||||
if datasets[i].Repo.Owner.IsOrganization() { | |||||
if datasets[i].Repo.Owner.IsUserPartOfOrg(opts.User.ID) { | |||||
log.Info("user is member of org.") | |||||
permission = true | |||||
} | |||||
} | |||||
if !permission { | if !permission { | ||||
isCollaborator, _ := datasets[i].Repo.IsCollaborator(opts.User.ID) | isCollaborator, _ := datasets[i].Repo.IsCollaborator(opts.User.ID) | ||||
if isCollaborator ||datasets[i].Repo.IsOwnedBy(opts.User.ID){ | |||||
isInRepoTeam,_:=datasets[i].Repo.IsInRepoTeam(opts.User.ID) | |||||
if isCollaborator ||isInRepoTeam { | |||||
log.Info("Collaborator user may visit the attach.") | log.Info("Collaborator user may visit the attach.") | ||||
permission = true | permission = true | ||||
} | } | ||||
@@ -150,6 +150,7 @@ func init() { | |||||
new(ResourceScene), | new(ResourceScene), | ||||
new(ResourceSceneSpec), | new(ResourceSceneSpec), | ||||
new(AdminOperateLog), | new(AdminOperateLog), | ||||
new(CloudbrainSpec), | |||||
new(CloudbrainTemp), | new(CloudbrainTemp), | ||||
new(DatasetReference), | new(DatasetReference), | ||||
) | ) | ||||
@@ -130,6 +130,20 @@ func (repo *Repository) IsCollaborator(userID int64) (bool, error) { | |||||
return repo.isCollaborator(x, userID) | return repo.isCollaborator(x, userID) | ||||
} | } | ||||
func (repo *Repository) IsInRepoTeam(userID int64) (bool, error) { | |||||
teams,err:=repo.GetRepoTeams() | |||||
if err!=nil || len(teams)==0{ | |||||
return false,err | |||||
} | |||||
for _,team :=range teams{ | |||||
if team.IsMember(userID){ | |||||
return true,nil | |||||
} | |||||
} | |||||
return false,nil | |||||
} | |||||
func (repo *Repository) changeCollaborationAccessMode(e Engine, uid int64, mode AccessMode) error { | func (repo *Repository) changeCollaborationAccessMode(e Engine, uid int64, mode AccessMode) error { | ||||
// Discard invalid input | // Discard invalid input | ||||
if mode <= AccessModeNone || mode > AccessModeOwner { | if mode <= AccessModeNone || mode > AccessModeOwner { | ||||
@@ -71,6 +71,8 @@ func (r ResourceQueueReq) ToDTO() ResourceQueue { | |||||
q.AiCenterName = "云脑一" | q.AiCenterName = "云脑一" | ||||
} else if r.AiCenterCode == AICenterOfCloudBrainTwo { | } else if r.AiCenterCode == AICenterOfCloudBrainTwo { | ||||
q.AiCenterName = "云脑二" | q.AiCenterName = "云脑二" | ||||
} else if r.AiCenterCode == AICenterOfChengdu { | |||||
q.AiCenterName = "启智成都智算" | |||||
} | } | ||||
} | } | ||||
return q | return q | ||||
@@ -2,6 +2,7 @@ package models | |||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
"fmt" | |||||
"xorm.io/builder" | "xorm.io/builder" | ||||
) | ) | ||||
@@ -22,6 +23,7 @@ type ResourceSpecification struct { | |||||
ShareMemGiB float32 | ShareMemGiB float32 | ||||
UnitPrice int | UnitPrice int | ||||
Status int | Status int | ||||
IsAvailable bool | |||||
IsAutomaticSync bool | IsAutomaticSync bool | ||||
CreatedTime timeutil.TimeStamp `xorm:"created"` | CreatedTime timeutil.TimeStamp `xorm:"created"` | ||||
CreatedBy int64 | CreatedBy int64 | ||||
@@ -40,6 +42,7 @@ func (r ResourceSpecification) ConvertToRes() *ResourceSpecificationRes { | |||||
GPUMemGiB: r.GPUMemGiB, | GPUMemGiB: r.GPUMemGiB, | ||||
UnitPrice: r.UnitPrice, | UnitPrice: r.UnitPrice, | ||||
Status: r.Status, | Status: r.Status, | ||||
IsAvailable: r.IsAvailable, | |||||
UpdatedTime: r.UpdatedTime, | UpdatedTime: r.UpdatedTime, | ||||
} | } | ||||
} | } | ||||
@@ -72,14 +75,16 @@ func (r ResourceSpecificationReq) ToDTO() ResourceSpecification { | |||||
IsAutomaticSync: r.IsAutomaticSync, | IsAutomaticSync: r.IsAutomaticSync, | ||||
CreatedBy: r.CreatorId, | CreatedBy: r.CreatorId, | ||||
UpdatedBy: r.CreatorId, | UpdatedBy: r.CreatorId, | ||||
IsAvailable: true, | |||||
} | } | ||||
} | } | ||||
type SearchResourceSpecificationOptions struct { | type SearchResourceSpecificationOptions struct { | ||||
ListOptions | ListOptions | ||||
QueueId int64 | |||||
Status int | |||||
Cluster string | |||||
QueueId int64 | |||||
Status int | |||||
Cluster string | |||||
AvailableCode int | |||||
} | } | ||||
type SearchResourceBriefSpecificationOptions struct { | type SearchResourceBriefSpecificationOptions struct { | ||||
@@ -113,6 +118,7 @@ type ResourceSpecificationRes struct { | |||||
ShareMemGiB float32 | ShareMemGiB float32 | ||||
UnitPrice int | UnitPrice int | ||||
Status int | Status int | ||||
IsAvailable bool | |||||
UpdatedTime timeutil.TimeStamp | 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) { | func InsertResourceSpecification(r ResourceSpecification) (int64, error) { | ||||
return x.Insert(&r) | return x.Insert(&r) | ||||
} | } | ||||
@@ -167,6 +220,11 @@ func SearchResourceSpecification(opts SearchResourceSpecificationOptions) (int64 | |||||
if opts.Cluster != "" { | if opts.Cluster != "" { | ||||
cond = cond.And(builder.Eq{"resource_queue.cluster": 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"})) | //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"). | n, err := x.Where(cond).Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | ||||
Unscoped().Count(&ResourceSpecAndQueue{}) | Unscoped().Count(&ResourceSpecAndQueue{}) | ||||
@@ -256,7 +314,7 @@ func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceS | |||||
return err | return err | ||||
} | } | ||||
if len(deleteIds) > 0 { | 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 | return err | ||||
} | } | ||||
if _, err = sess.In("spec_id", deleteIds).Delete(&ResourceSceneSpec{}); err != nil { | if _, err = sess.In("spec_id", deleteIds).Delete(&ResourceSceneSpec{}); err != nil { | ||||
@@ -267,7 +325,7 @@ func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceS | |||||
//update exists specs | //update exists specs | ||||
if len(updateList) > 0 { | if len(updateList) > 0 { | ||||
for _, v := range updateList { | 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 | return err | ||||
} | } | ||||
} | } | ||||
@@ -283,3 +341,221 @@ func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceS | |||||
return sess.Commit() | return sess.Commit() | ||||
} | } | ||||
//FindSpecs | |||||
func FindSpecs(opts FindSpecsOptions) ([]*Specification, error) { | |||||
var cond = builder.NewCond() | |||||
if !opts.RequestAll && opts.JobType != "" { | |||||
cond = cond.And(builder.Eq{"resource_scene.job_type": opts.JobType}) | |||||
} | |||||
if opts.ComputeResource != "" { | |||||
cond = cond.And(builder.Eq{"resource_queue.compute_resource": opts.ComputeResource}) | |||||
} | |||||
if opts.Cluster != "" { | |||||
cond = cond.And(builder.Eq{"resource_queue.cluster": opts.Cluster}) | |||||
} | |||||
if opts.AiCenterCode != "" { | |||||
cond = cond.And(builder.Eq{"resource_queue.ai_center_code": opts.AiCenterCode}) | |||||
} | |||||
if opts.SpecId > 0 { | |||||
cond = cond.And(builder.Eq{"resource_specification.id": opts.SpecId}) | |||||
} | |||||
if opts.QueueCode != "" { | |||||
cond = cond.And(builder.Eq{"resource_queue.queue_code": opts.QueueCode}) | |||||
} | |||||
if opts.SourceSpecId != "" { | |||||
cond = cond.And(builder.Eq{"resource_specification.source_spec_id": opts.SourceSpecId}) | |||||
} | |||||
if opts.UseAccCardsNum { | |||||
cond = cond.And(builder.Eq{"resource_specification.acc_cards_num": opts.AccCardsNum}) | |||||
} | |||||
if opts.AccCardType != "" { | |||||
cond = cond.And(builder.Eq{"resource_queue.acc_card_type": opts.AccCardType}) | |||||
} | |||||
if opts.UseCpuCores { | |||||
cond = cond.And(builder.Eq{"resource_specification.cpu_cores": opts.CpuCores}) | |||||
} | |||||
if opts.UseMemGiB { | |||||
cond = cond.And(builder.Eq{"resource_specification.mem_gi_b": opts.MemGiB}) | |||||
} | |||||
if opts.UseGPUMemGiB { | |||||
cond = cond.And(builder.Eq{"resource_specification.gpu_mem_gi_b": opts.GPUMemGiB}) | |||||
} | |||||
if opts.UseShareMemGiB { | |||||
cond = cond.And(builder.Eq{"resource_specification.share_mem_gi_b": opts.ShareMemGiB}) | |||||
} | |||||
r := make([]*Specification, 0) | |||||
s := x.Where(cond). | |||||
Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id") | |||||
if !opts.RequestAll { | |||||
s = s.Join("INNER", "resource_scene_spec", "resource_scene_spec.spec_id = resource_specification.id"). | |||||
Join("INNER", "resource_scene", "resource_scene_spec.scene_id = resource_scene.id") | |||||
} | |||||
err := s.OrderBy("resource_queue.compute_resource asc,resource_queue.acc_card_type asc,resource_specification.acc_cards_num asc,resource_specification.cpu_cores asc,resource_specification.mem_gi_b asc,resource_specification.share_mem_gi_b asc"). | |||||
Unscoped().Find(&r) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return r, nil | |||||
} | |||||
func InitQueueAndSpec(queue ResourceQueue, spec ResourceSpecification) (*Specification, error) { | |||||
sess := x.NewSession() | |||||
defer sess.Close() | |||||
sess.Begin() | |||||
param := ResourceQueue{ | |||||
QueueCode: queue.QueueCode, | |||||
Cluster: queue.Cluster, | |||||
AiCenterCode: queue.AiCenterCode, | |||||
ComputeResource: queue.ComputeResource, | |||||
AccCardType: queue.AccCardType, | |||||
} | |||||
_, err := sess.Get(¶m) | |||||
if err != nil { | |||||
sess.Rollback() | |||||
return nil, err | |||||
} | |||||
if param.ID == 0 { | |||||
_, err = sess.InsertOne(&queue) | |||||
if err != nil { | |||||
sess.Rollback() | |||||
return nil, err | |||||
} | |||||
} else { | |||||
queue = param | |||||
} | |||||
spec.QueueId = queue.ID | |||||
_, err = sess.InsertOne(&spec) | |||||
if err != nil { | |||||
sess.Rollback() | |||||
return nil, err | |||||
} | |||||
sess.Commit() | |||||
return BuildSpecification(queue, spec), nil | |||||
} | |||||
func BuildSpecification(queue ResourceQueue, spec ResourceSpecification) *Specification { | |||||
return &Specification{ | |||||
ID: spec.ID, | |||||
SourceSpecId: spec.SourceSpecId, | |||||
AccCardsNum: spec.AccCardsNum, | |||||
AccCardType: queue.AccCardType, | |||||
CpuCores: spec.CpuCores, | |||||
MemGiB: spec.MemGiB, | |||||
GPUMemGiB: spec.GPUMemGiB, | |||||
ShareMemGiB: spec.ShareMemGiB, | |||||
ComputeResource: queue.ComputeResource, | |||||
UnitPrice: spec.UnitPrice, | |||||
QueueId: queue.ID, | |||||
QueueCode: queue.QueueCode, | |||||
Cluster: queue.Cluster, | |||||
AiCenterCode: queue.AiCenterCode, | |||||
AiCenterName: queue.AiCenterName, | |||||
} | |||||
} | |||||
func GetCloudbrainOneAccCardType(queueCode string) string { | |||||
switch queueCode { | |||||
case "a100": | |||||
return "A100" | |||||
case "openidebug": | |||||
return "T4" | |||||
case "openidgx": | |||||
return "V100" | |||||
} | |||||
return "" | |||||
} | |||||
var cloudbrainTwoSpecsInitFlag = false | |||||
var cloudbrainTwoSpecs map[string]*Specification | |||||
func GetCloudbrainTwoSpecs() (map[string]*Specification, error) { | |||||
if !cloudbrainTwoSpecsInitFlag { | |||||
r, err := InitCloudbrainTwoSpecs() | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
cloudbrainTwoSpecsInitFlag = true | |||||
cloudbrainTwoSpecs = r | |||||
} | |||||
return cloudbrainTwoSpecs, nil | |||||
} | |||||
func InitCloudbrainTwoSpecs() (map[string]*Specification, error) { | |||||
r := make(map[string]*Specification, 0) | |||||
queue, err := GetResourceQueue(&ResourceQueue{QueueCode: "openisupport"}) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
if queue == nil { | |||||
queue = &ResourceQueue{ | |||||
QueueCode: "openisupport", | |||||
Cluster: OpenICluster, | |||||
AiCenterCode: AICenterOfCloudBrainTwo, | |||||
AiCenterName: "云脑二", | |||||
ComputeResource: NPU, | |||||
AccCardType: "ASCEND910", | |||||
Remark: "处理历史云脑任务时自动生成", | |||||
} | |||||
_, err = x.InsertOne(queue) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
} | |||||
for i := 1; i <= 8; i = i * 2 { | |||||
sourceSpecId := "modelarts.bm.910.arm.public." + fmt.Sprint(i) | |||||
spec, err := GetResourceSpecification(&ResourceSpecification{ | |||||
SourceSpecId: sourceSpecId, | |||||
QueueId: queue.ID, | |||||
}) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
if spec == nil { | |||||
spec = &ResourceSpecification{ | |||||
QueueId: queue.ID, | |||||
SourceSpecId: sourceSpecId, | |||||
AccCardsNum: i, | |||||
CpuCores: i * 24, | |||||
MemGiB: float32(i * 256), | |||||
GPUMemGiB: float32(32), | |||||
Status: SpecOffShelf, | |||||
IsAvailable: true, | |||||
} | |||||
_, err = x.Insert(spec) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
} | |||||
r[sourceSpecId] = BuildSpecification(*queue, *spec) | |||||
} | |||||
return r, nil | |||||
} | |||||
var grampusSpecsInitFlag = false | |||||
var grampusSpecs map[string]*Specification | |||||
func GetGrampusSpecs() (map[string]*Specification, error) { | |||||
if !grampusSpecsInitFlag { | |||||
specMap := make(map[string]*Specification, 0) | |||||
r, err := FindSpecs(FindSpecsOptions{ | |||||
Cluster: C2NetCluster, | |||||
RequestAll: true, | |||||
}) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
for _, spec := range r { | |||||
specMap[spec.SourceSpecId] = spec | |||||
specMap[spec.SourceSpecId+"_"+spec.AiCenterCode] = spec | |||||
} | |||||
grampusSpecsInitFlag = true | |||||
grampusSpecs = specMap | |||||
} | |||||
return grampusSpecs, nil | |||||
} |
@@ -24,6 +24,7 @@ type CreateCloudBrainForm struct { | |||||
Params string `form:"run_para_list"` | Params string `form:"run_para_list"` | ||||
BranchName string `form:"branch_name"` | BranchName string `form:"branch_name"` | ||||
DatasetName string `form:"dataset_name"` | DatasetName string `form:"dataset_name"` | ||||
SpecId int64 `form:"spec_id"` | |||||
} | } | ||||
type CommitImageCloudBrainForm struct { | type CommitImageCloudBrainForm struct { | ||||
@@ -72,6 +73,7 @@ type CreateCloudBrainInferencForm struct { | |||||
CkptName string `form:"ckpt_name" binding:"Required"` | CkptName string `form:"ckpt_name" binding:"Required"` | ||||
LabelName string `form:"label_names" binding:"Required"` | LabelName string `form:"label_names" binding:"Required"` | ||||
DatasetName string `form:"dataset_name"` | DatasetName string `form:"dataset_name"` | ||||
SpecId int64 `form:"spec_id"` | |||||
} | } | ||||
func (f *CreateCloudBrainForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateCloudBrainForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
@@ -11,15 +11,14 @@ type CreateGrampusTrainJobForm struct { | |||||
Attachment string `form:"attachment" binding:"Required"` | Attachment string `form:"attachment" binding:"Required"` | ||||
BootFile string `form:"boot_file" binding:"Required"` | BootFile string `form:"boot_file" binding:"Required"` | ||||
ImageID string `form:"image_id" binding:"Required"` | ImageID string `form:"image_id" binding:"Required"` | ||||
FlavorID string `form:"flavor" binding:"Required"` | |||||
Params string `form:"run_para_list" binding:"Required"` | Params string `form:"run_para_list" binding:"Required"` | ||||
Description string `form:"description"` | Description string `form:"description"` | ||||
BranchName string `form:"branch_name" binding:"Required"` | BranchName string `form:"branch_name" binding:"Required"` | ||||
FlavorName string `form:"flavor_name" binding:"Required"` | |||||
EngineName string `form:"engine_name" binding:"Required"` | EngineName string `form:"engine_name" binding:"Required"` | ||||
WorkServerNumber int `form:"work_server_number" binding:"Required"` | WorkServerNumber int `form:"work_server_number" binding:"Required"` | ||||
Image string `form:"image"` | Image string `form:"image"` | ||||
DatasetName string `form:"dataset_name"` | DatasetName string `form:"dataset_name"` | ||||
SpecId int64 `form:"spec_id"` | |||||
} | } | ||||
func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
@@ -22,6 +22,7 @@ type CreateModelArtsNotebookForm struct { | |||||
Description string `form:"description"` | Description string `form:"description"` | ||||
Flavor string `form:"flavor" binding:"Required"` | Flavor string `form:"flavor" binding:"Required"` | ||||
ImageId string `form:"image_id" 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 { | 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"` | VersionName string `form:"version_name" binding:"Required"` | ||||
FlavorName string `form:"flaver_names" binding:"Required"` | FlavorName string `form:"flaver_names" binding:"Required"` | ||||
EngineName string `form:"engine_names" binding:"Required"` | EngineName string `form:"engine_names" binding:"Required"` | ||||
SpecId int64 `form:"spec_id" binding:"Required"` | |||||
} | } | ||||
type CreateModelArtsInferenceJobForm struct { | type CreateModelArtsInferenceJobForm struct { | ||||
@@ -71,6 +73,7 @@ type CreateModelArtsInferenceJobForm struct { | |||||
ModelName string `form:"model_name" binding:"Required"` | ModelName string `form:"model_name" binding:"Required"` | ||||
ModelVersion string `form:"model_version" binding:"Required"` | ModelVersion string `form:"model_version" binding:"Required"` | ||||
CkptName string `form:"ckpt_name" 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 { | func (f *CreateModelArtsTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
@@ -62,7 +62,7 @@ type CloudbrainStopMsg struct { | |||||
func (CloudbrainStopMsg) Data(ctx *TemplateContext) *DefaultWechatTemplate { | func (CloudbrainStopMsg) Data(ctx *TemplateContext) *DefaultWechatTemplate { | ||||
return &DefaultWechatTemplate{ | return &DefaultWechatTemplate{ | ||||
First: TemplateValue{Value: setting.CloudbrainStoppedTitle}, | |||||
First: TemplateValue{Value: fmt.Sprintf(setting.CloudbrainStoppedTitle, ctx.Cloudbrain.Status)}, | |||||
Keyword1: TemplateValue{Value: ctx.Cloudbrain.DisplayJobName}, | Keyword1: TemplateValue{Value: ctx.Cloudbrain.DisplayJobName}, | ||||
Keyword2: TemplateValue{Value: getJobTypeDisplayName(ctx.Cloudbrain.JobType)}, | Keyword2: TemplateValue{Value: getJobTypeDisplayName(ctx.Cloudbrain.JobType)}, | ||||
Keyword3: TemplateValue{Value: time.Unix(int64(ctx.Cloudbrain.CreatedUnix), 0).Format("2006-01-02 15:04:05")}, | Keyword3: TemplateValue{Value: time.Unix(int64(ctx.Cloudbrain.CreatedUnix), 0).Format("2006-01-02 15:04:05")}, | ||||
@@ -20,7 +20,7 @@ import ( | |||||
const ( | const ( | ||||
//Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` | //Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` | ||||
//CommandBenchmark = `echo "start benchmark";python /code/test.py;echo "end benchmark"` | //CommandBenchmark = `echo "start benchmark";python /code/test.py;echo "end benchmark"` | ||||
CommandBenchmark = `echo "start benchmark";cd /benchmark && bash run_bk.sh;echo "end benchmark"` | |||||
CommandBenchmark = `cd /benchmark && bash run_bk.sh >/model/benchmark-log.txt` | |||||
CodeMountPath = "/code" | CodeMountPath = "/code" | ||||
DataSetMountPath = "/dataset" | DataSetMountPath = "/dataset" | ||||
ModelMountPath = "/model" | ModelMountPath = "/model" | ||||
@@ -30,8 +30,8 @@ const ( | |||||
Snn4imagenetMountPath = "/snn4imagenet" | Snn4imagenetMountPath = "/snn4imagenet" | ||||
BrainScoreMountPath = "/brainscore" | BrainScoreMountPath = "/brainscore" | ||||
TaskInfoName = "/taskInfo" | TaskInfoName = "/taskInfo" | ||||
Snn4imagenetCommand = `/opt/conda/bin/python /snn4imagenet/testSNN_script.py --modelname '%s' --modelpath '/dataset' --modeldescription '%s'` | |||||
BrainScoreCommand = `bash /brainscore/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/dataset' -d '%s'` | |||||
Snn4imagenetCommand = `/opt/conda/bin/python /snn4imagenet/testSNN_script.py --modelname '%s' --modelpath '/dataset' --modeldescription '%s' >/model/benchmark-log.txt` | |||||
BrainScoreCommand = `bash /brainscore/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/dataset' -d '%s' >/model/benchmark-log.txt` | |||||
SubTaskName = "task1" | SubTaskName = "task1" | ||||
@@ -61,7 +61,6 @@ type GenerateCloudBrainTaskReq struct { | |||||
Snn4ImageNetPath string | Snn4ImageNetPath string | ||||
BrainScorePath string | BrainScorePath string | ||||
JobType string | JobType string | ||||
GpuQueue string | |||||
Description string | Description string | ||||
BranchName string | BranchName string | ||||
BootFile string | BootFile string | ||||
@@ -72,13 +71,13 @@ type GenerateCloudBrainTaskReq struct { | |||||
DatasetInfos map[string]models.DatasetInfo | DatasetInfos map[string]models.DatasetInfo | ||||
BenchmarkTypeID int | BenchmarkTypeID int | ||||
BenchmarkChildTypeID int | BenchmarkChildTypeID int | ||||
ResourceSpecId int | |||||
ResultPath string | ResultPath string | ||||
TrainUrl string | TrainUrl string | ||||
ModelName string | ModelName string | ||||
ModelVersion string | ModelVersion string | ||||
CkptName string | CkptName string | ||||
LabelName string | LabelName string | ||||
Spec *models.Specification | |||||
} | } | ||||
func GetCloudbrainDebugCommand() string { | func GetCloudbrainDebugCommand() string { | ||||
@@ -227,50 +226,9 @@ func AdminOrImageCreaterRight(ctx *context.Context) { | |||||
} | } | ||||
func GenerateTask(req GenerateCloudBrainTaskReq) error { | func GenerateTask(req GenerateCloudBrainTaskReq) error { | ||||
var resourceSpec *models.ResourceSpec | |||||
var versionCount int | var versionCount int | ||||
if req.JobType == string(models.JobTypeTrain) { | if req.JobType == string(models.JobTypeTrain) { | ||||
versionCount = 1 | 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{ | volumes := []models.Volume{ | ||||
@@ -342,7 +300,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||||
jobResult, err := CreateJob(req.JobName, models.CreateJobParams{ | jobResult, err := CreateJob(req.JobName, models.CreateJobParams{ | ||||
JobName: req.JobName, | JobName: req.JobName, | ||||
RetryCount: 1, | RetryCount: 1, | ||||
GpuType: req.GpuQueue, | |||||
GpuType: req.Spec.QueueCode, | |||||
Image: req.Image, | Image: req.Image, | ||||
TaskRoles: []models.TaskRole{ | TaskRoles: []models.TaskRole{ | ||||
{ | { | ||||
@@ -350,10 +308,10 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||||
TaskNumber: 1, | TaskNumber: 1, | ||||
MinSucceededTaskCount: 1, | MinSucceededTaskCount: 1, | ||||
MinFailedTaskCount: 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, | Command: req.Command, | ||||
NeedIBDevice: false, | NeedIBDevice: false, | ||||
IsMainRole: false, | IsMainRole: false, | ||||
@@ -384,8 +342,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||||
Type: models.TypeCloudBrainOne, | Type: models.TypeCloudBrainOne, | ||||
Uuid: req.Uuids, | Uuid: req.Uuids, | ||||
Image: req.Image, | Image: req.Image, | ||||
GpuQueue: req.GpuQueue, | |||||
ResourceSpecId: req.ResourceSpecId, | |||||
GpuQueue: req.Spec.QueueCode, | |||||
ComputeResource: models.GPUResource, | ComputeResource: models.GPUResource, | ||||
BenchmarkTypeID: req.BenchmarkTypeID, | BenchmarkTypeID: req.BenchmarkTypeID, | ||||
BenchmarkChildTypeID: req.BenchmarkChildTypeID, | BenchmarkChildTypeID: req.BenchmarkChildTypeID, | ||||
@@ -405,6 +362,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
CommitID: req.CommitID, | CommitID: req.CommitID, | ||||
Spec: req.Spec, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
@@ -416,6 +374,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||||
log.Error("GetCloudbrainByJobID failed: %v", err.Error()) | log.Error("GetCloudbrainByJobID failed: %v", err.Error()) | ||||
return err | return err | ||||
} | } | ||||
stringId := strconv.FormatInt(task.ID, 10) | stringId := strconv.FormatInt(task.ID, 10) | ||||
if IsBenchmarkJob(req.JobType) { | 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 { | func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error { | ||||
jobName := task.JobName | 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 | var datasetInfos map[string]models.DatasetInfo | ||||
if task.Uuid != "" { | if task.Uuid != "" { | ||||
var err error | var err error | ||||
@@ -547,10 +488,10 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||||
TaskNumber: 1, | TaskNumber: 1, | ||||
MinSucceededTaskCount: 1, | MinSucceededTaskCount: 1, | ||||
MinFailedTaskCount: 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, | Command: GetCloudbrainDebugCommand(), //Command, | ||||
NeedIBDevice: false, | NeedIBDevice: false, | ||||
IsMainRole: false, | IsMainRole: false, | ||||
@@ -588,6 +529,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
BranchName: task.BranchName, | BranchName: task.BranchName, | ||||
Spec: spec, | |||||
} | } | ||||
err = models.RestartCloudbrain(task, newTask) | err = models.RestartCloudbrain(task, newTask) | ||||
@@ -30,18 +30,17 @@ const ( | |||||
var ( | var ( | ||||
poolInfos *models.PoolInfos | poolInfos *models.PoolInfos | ||||
FlavorInfos *models.FlavorInfos | |||||
ImageInfos *models.ImageInfosModelArts | |||||
FlavorInfos *setting.StFlavorInfos | |||||
ImageInfos *setting.StImageInfosModelArts | |||||
SpecialPools *models.SpecialPools | SpecialPools *models.SpecialPools | ||||
) | ) | ||||
type GenerateTrainJobReq struct { | 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 | DisplayJobName string | ||||
Uuid string | Uuid string | ||||
@@ -58,7 +57,6 @@ type GenerateTrainJobReq struct { | |||||
BranchName string | BranchName string | ||||
PreVersionId int64 | PreVersionId int64 | ||||
PreVersionName string | PreVersionName string | ||||
FlavorName string | |||||
VersionCount int | VersionCount int | ||||
EngineName string | EngineName string | ||||
TotalVersionCount int | TotalVersionCount int | ||||
@@ -66,6 +64,7 @@ type GenerateTrainJobReq struct { | |||||
ProcessType string | ProcessType string | ||||
DatasetName string | DatasetName string | ||||
Params string | Params string | ||||
Spec *models.Specification | |||||
} | } | ||||
func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error) { | 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, | Name: req.JobName, | ||||
Command: req.Command, | Command: req.Command, | ||||
ResourceSpecId: req.ResourceSpecId, | |||||
ResourceSpecId: req.Spec.SourceSpecId, | |||||
ImageId: req.ImageId, | ImageId: req.ImageId, | ||||
ImageUrl: req.ImageUrl, | ImageUrl: req.ImageUrl, | ||||
CenterID: centerID, | CenterID: centerID, | ||||
@@ -114,15 +113,14 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
Parameters: req.Params, | Parameters: req.Params, | ||||
BootFile: req.BootFile, | BootFile: req.BootFile, | ||||
DataUrl: req.DataUrl, | DataUrl: req.DataUrl, | ||||
FlavorCode: req.ResourceSpecId, | |||||
Description: req.Description, | Description: req.Description, | ||||
WorkServerNumber: req.WorkServerNumber, | WorkServerNumber: req.WorkServerNumber, | ||||
FlavorName: req.FlavorName, | |||||
EngineName: req.EngineName, | EngineName: req.EngineName, | ||||
VersionCount: req.VersionCount, | VersionCount: req.VersionCount, | ||||
TotalVersionCount: req.TotalVersionCount, | TotalVersionCount: req.TotalVersionCount, | ||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
Spec: req.Spec, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
@@ -1,6 +1,7 @@ | |||||
package modelarts | package modelarts | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/modelarts_cd" | |||||
"encoding/json" | "encoding/json" | ||||
"errors" | "errors" | ||||
"fmt" | "fmt" | ||||
@@ -68,10 +69,9 @@ const ( | |||||
var ( | var ( | ||||
poolInfos *models.PoolInfos | poolInfos *models.PoolInfos | ||||
FlavorInfos *models.FlavorInfos | |||||
ImageInfos *models.ImageInfosModelArts | |||||
TrainFlavorInfos *Flavor | TrainFlavorInfos *Flavor | ||||
SpecialPools *models.SpecialPools | |||||
SpecialPools *models.SpecialPools | |||||
MultiNodeConfig *MultiNodes | |||||
) | ) | ||||
type GenerateTrainJobReq struct { | type GenerateTrainJobReq struct { | ||||
@@ -84,7 +84,6 @@ type GenerateTrainJobReq struct { | |||||
BootFileUrl string | BootFileUrl string | ||||
DataUrl string | DataUrl string | ||||
TrainUrl string | TrainUrl string | ||||
FlavorCode string | |||||
LogUrl string | LogUrl string | ||||
PoolID string | PoolID string | ||||
WorkServerNumber int | WorkServerNumber int | ||||
@@ -96,6 +95,7 @@ type GenerateTrainJobReq struct { | |||||
BranchName string | BranchName string | ||||
PreVersionId int64 | PreVersionId int64 | ||||
PreVersionName string | PreVersionName string | ||||
FlavorCode string | |||||
FlavorName string | FlavorName string | ||||
VersionCount int | VersionCount int | ||||
EngineName string | EngineName string | ||||
@@ -103,6 +103,7 @@ type GenerateTrainJobReq struct { | |||||
UserImageUrl string | UserImageUrl string | ||||
UserCommand string | UserCommand string | ||||
DatasetName string | DatasetName string | ||||
Spec *models.Specification | |||||
} | } | ||||
type GenerateInferenceJobReq struct { | type GenerateInferenceJobReq struct { | ||||
@@ -115,7 +116,6 @@ type GenerateInferenceJobReq struct { | |||||
BootFileUrl string | BootFileUrl string | ||||
DataUrl string | DataUrl string | ||||
TrainUrl string | TrainUrl string | ||||
FlavorCode string | |||||
LogUrl string | LogUrl string | ||||
PoolID string | PoolID string | ||||
WorkServerNumber int | WorkServerNumber int | ||||
@@ -134,6 +134,7 @@ type GenerateInferenceJobReq struct { | |||||
ModelVersion string | ModelVersion string | ||||
CkptName string | CkptName string | ||||
ResultUrl string | ResultUrl string | ||||
Spec *models.Specification | |||||
DatasetName string | DatasetName string | ||||
} | } | ||||
@@ -166,6 +167,14 @@ type ResourcePool struct { | |||||
} `json:"resource_pool"` | } `json:"resource_pool"` | ||||
} | } | ||||
type MultiNodes struct{ | |||||
Info []OrgMultiNode `json:"multinode"` | |||||
} | |||||
type OrgMultiNode struct{ | |||||
Org string `json:"org"` | |||||
Node []int `json:"node"` | |||||
} | |||||
// type Parameter struct { | // type Parameter struct { | ||||
// Label string `json:"label"` | // Label string `json:"label"` | ||||
// Value string `json:"value"` | // Value string `json:"value"` | ||||
@@ -257,7 +266,7 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin | |||||
return nil | 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 { | if poolInfos == nil { | ||||
json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | ||||
} | } | ||||
@@ -271,7 +280,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc | |||||
jobResult, err := createNotebook2(models.CreateNotebook2Params{ | jobResult, err := createNotebook2(models.CreateNotebook2Params{ | ||||
JobName: jobName, | JobName: jobName, | ||||
Description: description, | Description: description, | ||||
Flavor: flavor, | |||||
Flavor: spec.SourceSpecId, | |||||
Duration: autoStopDurationMs, | Duration: autoStopDurationMs, | ||||
ImageID: imageId, | ImageID: imageId, | ||||
PoolID: poolInfos.PoolInfo[0].PoolId, | PoolID: poolInfos.PoolInfo[0].PoolId, | ||||
@@ -308,7 +317,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc | |||||
RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
JobID: jobResult.ID, | JobID: jobResult.ID, | ||||
JobName: jobName, | JobName: jobName, | ||||
FlavorCode: flavor, | |||||
FlavorCode: spec.SourceSpecId, | |||||
DisplayJobName: displayJobName, | DisplayJobName: displayJobName, | ||||
JobType: string(models.JobTypeDebug), | JobType: string(models.JobTypeDebug), | ||||
Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
@@ -318,6 +327,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc | |||||
Description: description, | Description: description, | ||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
Spec: spec, | |||||
} | } | ||||
err = models.CreateCloudbrain(task) | err = models.CreateCloudbrain(task) | ||||
@@ -348,7 +358,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
PoolID: req.PoolID, | PoolID: req.PoolID, | ||||
CreateVersion: true, | CreateVersion: true, | ||||
Flavor: models.Flavor{ | Flavor: models.Flavor{ | ||||
Code: req.FlavorCode, | |||||
Code: req.Spec.SourceSpecId, | |||||
}, | }, | ||||
Parameter: req.Parameters, | Parameter: req.Parameters, | ||||
UserImageUrl: req.UserImageUrl, | UserImageUrl: req.UserImageUrl, | ||||
@@ -370,7 +380,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
PoolID: req.PoolID, | PoolID: req.PoolID, | ||||
CreateVersion: true, | CreateVersion: true, | ||||
Flavor: models.Flavor{ | Flavor: models.Flavor{ | ||||
Code: req.FlavorCode, | |||||
Code: req.Spec.SourceSpecId, | |||||
}, | }, | ||||
Parameter: req.Parameters, | Parameter: req.Parameters, | ||||
}, | }, | ||||
@@ -419,7 +429,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
BootFile: req.BootFile, | BootFile: req.BootFile, | ||||
DataUrl: req.DataUrl, | DataUrl: req.DataUrl, | ||||
LogUrl: req.LogUrl, | LogUrl: req.LogUrl, | ||||
FlavorCode: req.FlavorCode, | |||||
FlavorCode: req.Spec.SourceSpecId, | |||||
Description: req.Description, | Description: req.Description, | ||||
WorkServerNumber: req.WorkServerNumber, | WorkServerNumber: req.WorkServerNumber, | ||||
FlavorName: req.FlavorName, | FlavorName: req.FlavorName, | ||||
@@ -428,6 +438,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
TotalVersionCount: req.TotalVersionCount, | TotalVersionCount: req.TotalVersionCount, | ||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
Spec: req.Spec, | |||||
}) | }) | ||||
if createErr != nil { | if createErr != nil { | ||||
@@ -479,7 +490,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||||
LogUrl: req.LogUrl, | LogUrl: req.LogUrl, | ||||
PoolID: req.PoolID, | PoolID: req.PoolID, | ||||
Flavor: models.Flavor{ | Flavor: models.Flavor{ | ||||
Code: req.FlavorCode, | |||||
Code: req.Spec.SourceSpecId, | |||||
}, | }, | ||||
Parameter: req.Parameters, | Parameter: req.Parameters, | ||||
PreVersionId: req.PreVersionId, | PreVersionId: req.PreVersionId, | ||||
@@ -500,7 +511,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||||
LogUrl: req.LogUrl, | LogUrl: req.LogUrl, | ||||
PoolID: req.PoolID, | PoolID: req.PoolID, | ||||
Flavor: models.Flavor{ | Flavor: models.Flavor{ | ||||
Code: req.FlavorCode, | |||||
Code: req.Spec.SourceSpecId, | |||||
}, | }, | ||||
Parameter: req.Parameters, | Parameter: req.Parameters, | ||||
PreVersionId: req.PreVersionId, | PreVersionId: req.PreVersionId, | ||||
@@ -567,7 +578,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||||
DataUrl: req.DataUrl, | DataUrl: req.DataUrl, | ||||
LogUrl: req.LogUrl, | LogUrl: req.LogUrl, | ||||
PreVersionId: req.PreVersionId, | PreVersionId: req.PreVersionId, | ||||
FlavorCode: req.FlavorCode, | |||||
FlavorCode: req.Spec.SourceSpecId, | |||||
Description: req.Description, | Description: req.Description, | ||||
WorkServerNumber: req.WorkServerNumber, | WorkServerNumber: req.WorkServerNumber, | ||||
FlavorName: req.FlavorName, | FlavorName: req.FlavorName, | ||||
@@ -576,6 +587,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||||
VersionCount: VersionListCount + 1, | VersionCount: VersionListCount + 1, | ||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
Spec: req.Spec, | |||||
}) | }) | ||||
if createErr != nil { | if createErr != nil { | ||||
log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, createErr.Error()) | log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, createErr.Error()) | ||||
@@ -666,7 +678,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
PoolID: req.PoolID, | PoolID: req.PoolID, | ||||
CreateVersion: true, | CreateVersion: true, | ||||
Flavor: models.Flavor{ | Flavor: models.Flavor{ | ||||
Code: req.FlavorCode, | |||||
Code: req.Spec.SourceSpecId, | |||||
}, | }, | ||||
Parameter: req.Parameters, | Parameter: req.Parameters, | ||||
}, | }, | ||||
@@ -718,7 +730,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
BootFile: req.BootFile, | BootFile: req.BootFile, | ||||
DataUrl: req.DataUrl, | DataUrl: req.DataUrl, | ||||
LogUrl: req.LogUrl, | LogUrl: req.LogUrl, | ||||
FlavorCode: req.FlavorCode, | |||||
FlavorCode: req.Spec.SourceSpecId, | |||||
Description: req.Description, | Description: req.Description, | ||||
WorkServerNumber: req.WorkServerNumber, | WorkServerNumber: req.WorkServerNumber, | ||||
FlavorName: req.FlavorName, | FlavorName: req.FlavorName, | ||||
@@ -734,6 +746,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
ResultUrl: req.ResultUrl, | ResultUrl: req.ResultUrl, | ||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
Spec: req.Spec, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
@@ -748,11 +761,7 @@ func GetNotebookImageName(imageId string) (string, error) { | |||||
var validImage = false | var validImage = false | ||||
var imageName = "" | var imageName = "" | ||||
if ImageInfos == nil { | |||||
json.Unmarshal([]byte(setting.ImageInfos), &ImageInfos) | |||||
} | |||||
for _, imageInfo := range ImageInfos.ImageInfo { | |||||
for _, imageInfo := range setting.StImageInfos.ImageInfo { | |||||
if imageInfo.Id == imageId { | if imageInfo.Id == imageId { | ||||
validImage = true | validImage = true | ||||
imageName = imageInfo.Value | imageName = imageInfo.Value | ||||
@@ -773,6 +782,13 @@ func InitSpecialPool() { | |||||
} | } | ||||
} | } | ||||
func InitMultiNode(){ | |||||
if MultiNodeConfig ==nil && setting.ModelArtsMultiNode!=""{ | |||||
json.Unmarshal([]byte(setting.ModelArtsMultiNode), &MultiNodeConfig) | |||||
} | |||||
} | |||||
func HandleTrainJobInfo(task *models.Cloudbrain) error { | func HandleTrainJobInfo(task *models.Cloudbrain) error { | ||||
result, err := GetTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | result, err := GetTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | ||||
@@ -809,8 +825,13 @@ func HandleTrainJobInfo(task *models.Cloudbrain) error { | |||||
} | } | ||||
func HandleNotebookInfo(task *models.Cloudbrain) error { | func HandleNotebookInfo(task *models.Cloudbrain) error { | ||||
result, err := GetNotebook2(task.JobID) | |||||
var result *models.GetNotebook2Result | |||||
var err error | |||||
if task.Type == models.TypeCloudBrainTwo { | |||||
result, err = GetNotebook2(task.JobID) | |||||
} else if task.Type == models.TypeCDCenter { | |||||
result, err = modelarts_cd.GetNotebook(task.JobID) | |||||
} | |||||
if err != nil { | if err != nil { | ||||
log.Error("GetNotebook2(%s) failed:%v", task.DisplayJobName, err) | log.Error("GetNotebook2(%s) failed:%v", task.DisplayJobName, err) | ||||
return err | return err | ||||
@@ -0,0 +1,215 @@ | |||||
package modelarts_cd | |||||
import ( | |||||
"errors" | |||||
"strconv" | |||||
"strings" | |||||
"code.gitea.io/gitea/models" | |||||
"code.gitea.io/gitea/modules/context" | |||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/notification" | |||||
"code.gitea.io/gitea/modules/setting" | |||||
"code.gitea.io/gitea/modules/timeutil" | |||||
) | |||||
const ( | |||||
//notebook | |||||
storageTypeOBS = "obs" | |||||
autoStopDuration = 4 * 60 * 60 | |||||
autoStopDurationMs = 4 * 60 * 60 * 1000 | |||||
MORDELART_USER_IMAGE_ENGINE_ID = -1 | |||||
DataSetMountPath = "/home/ma-user/work" | |||||
NotebookEnv = "Python3" | |||||
NotebookType = "Ascend" | |||||
FlavorInfo = "Ascend: 1*Ascend 910 CPU: 24 核 96GiB (modelarts.kat1.xlarge)" | |||||
//train-job | |||||
CodePath = "/code/" | |||||
OutputPath = "/output/" | |||||
ResultPath = "/result/" | |||||
LogPath = "/log/" | |||||
JobPath = "/job/" | |||||
OrderDesc = "desc" //向下查询 | |||||
OrderAsc = "asc" //向上查询 | |||||
Lines = 500 | |||||
TrainUrl = "train_url" | |||||
DataUrl = "data_url" | |||||
MultiDataUrl = "multi_data_url" | |||||
ResultUrl = "result_url" | |||||
CkptUrl = "ckpt_url" | |||||
DeviceTarget = "device_target" | |||||
Ascend = "Ascend" | |||||
PerPage = 10 | |||||
IsLatestVersion = "1" | |||||
NotLatestVersion = "0" | |||||
VersionCountOne = 1 | |||||
SortByCreateTime = "create_time" | |||||
ConfigTypeCustom = "custom" | |||||
TotalVersionCount = 1 | |||||
) | |||||
var () | |||||
type VersionInfo struct { | |||||
Version []struct { | |||||
ID int `json:"id"` | |||||
Value string `json:"value"` | |||||
Url string `json:"url"` | |||||
} `json:"version"` | |||||
} | |||||
type Flavor struct { | |||||
Info []struct { | |||||
Code string `json:"code"` | |||||
Value string `json:"value"` | |||||
} `json:"flavor"` | |||||
} | |||||
type Engine struct { | |||||
Info []struct { | |||||
ID int `json:"id"` | |||||
Value string `json:"value"` | |||||
} `json:"engine"` | |||||
} | |||||
type ResourcePool struct { | |||||
Info []struct { | |||||
ID string `json:"id"` | |||||
Value string `json:"value"` | |||||
} `json:"resource_pool"` | |||||
} | |||||
type Parameters struct { | |||||
Parameter []struct { | |||||
Label string `json:"label"` | |||||
Value string `json:"value"` | |||||
} `json:"parameter"` | |||||
} | |||||
func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification) error { | |||||
imageName, err := GetNotebookImageName(imageId) | |||||
if err != nil { | |||||
log.Error("GetNotebookImageName failed: %v", err.Error()) | |||||
return err | |||||
} | |||||
createTime := timeutil.TimeStampNow() | |||||
jobResult, err := createNotebook(models.CreateNotebookWithoutPoolParams{ | |||||
JobName: jobName, | |||||
Description: description, | |||||
Flavor: spec.SourceSpecId, | |||||
Duration: autoStopDurationMs, | |||||
ImageID: imageId, | |||||
Feature: models.NotebookFeature, | |||||
Volume: models.VolumeReq{ | |||||
Capacity: setting.Capacity, | |||||
Category: models.EVSCategory, | |||||
Ownership: models.ManagedOwnership, | |||||
}, | |||||
WorkspaceID: "0", | |||||
}) | |||||
if err != nil { | |||||
log.Error("createNotebook failed: %v", err.Error()) | |||||
if strings.HasPrefix(err.Error(), UnknownErrorPrefix) { | |||||
log.Info("(%s)unknown error, set temp status", displayJobName) | |||||
errTemp := models.InsertCloudbrainTemp(&models.CloudbrainTemp{ | |||||
JobID: models.TempJobId, | |||||
VersionID: models.TempVersionId, | |||||
Status: models.TempJobStatus, | |||||
Type: models.TypeCDCenter, | |||||
JobName: jobName, | |||||
JobType: string(models.JobTypeDebug), | |||||
}) | |||||
if errTemp != nil { | |||||
log.Error("InsertCloudbrainTemp failed: %v", errTemp.Error()) | |||||
return errTemp | |||||
} | |||||
} | |||||
return err | |||||
} | |||||
task := &models.Cloudbrain{ | |||||
Status: jobResult.Status, | |||||
UserID: ctx.User.ID, | |||||
RepoID: ctx.Repo.Repository.ID, | |||||
JobID: jobResult.ID, | |||||
JobName: jobName, | |||||
FlavorCode: spec.SourceSpecId, | |||||
DisplayJobName: displayJobName, | |||||
JobType: string(models.JobTypeDebug), | |||||
Type: models.TypeCDCenter, | |||||
Uuid: uuid, | |||||
ComputeResource: models.NPUResource, | |||||
Image: imageName, | |||||
Description: description, | |||||
CreatedUnix: createTime, | |||||
UpdatedUnix: createTime, | |||||
Spec: spec, | |||||
} | |||||
err = models.CreateCloudbrain(task) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
stringId := strconv.FormatInt(task.ID, 10) | |||||
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask) | |||||
return nil | |||||
} | |||||
func GetNotebookImageName(imageId string) (string, error) { | |||||
var validImage = false | |||||
var imageName = "" | |||||
for _, imageInfo := range setting.StImageInfos.ImageInfo { | |||||
if imageInfo.Id == imageId { | |||||
validImage = true | |||||
imageName = imageInfo.Value | |||||
} | |||||
} | |||||
if !validImage { | |||||
log.Error("the image id(%s) is invalid", imageId) | |||||
return imageName, errors.New("the image id is invalid") | |||||
} | |||||
return imageName, nil | |||||
} | |||||
/* | |||||
func HandleNotebookInfo(task *models.Cloudbrain) error { | |||||
result, err := GetNotebook(task.JobID) | |||||
if err != nil { | |||||
log.Error("GetNotebook2(%s) failed:%v", task.DisplayJobName, err) | |||||
return err | |||||
} | |||||
if result != nil { | |||||
oldStatus := task.Status | |||||
task.Status = result.Status | |||||
if task.StartTime == 0 && result.Lease.UpdateTime > 0 { | |||||
task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | |||||
} | |||||
if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | |||||
task.EndTime = timeutil.TimeStampNow() | |||||
} | |||||
task.CorrectCreateUnix() | |||||
task.ComputeAndSetDuration() | |||||
if oldStatus != task.Status { | |||||
notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
} | |||||
if task.FlavorCode == "" { | |||||
task.FlavorCode = result.Flavor | |||||
} | |||||
err = models.UpdateJob(task) | |||||
if err != nil { | |||||
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err) | |||||
return err | |||||
} | |||||
} | |||||
return nil | |||||
} | |||||
*/ |
@@ -0,0 +1,220 @@ | |||||
package modelarts_cd | |||||
import ( | |||||
"bytes" | |||||
"code.gitea.io/gitea/modules/modelarts_gateway/core" | |||||
"crypto/tls" | |||||
"encoding/json" | |||||
"fmt" | |||||
"io/ioutil" | |||||
"net/http" | |||||
"strconv" | |||||
"time" | |||||
"code.gitea.io/gitea/models" | |||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/setting" | |||||
) | |||||
var ( | |||||
httpClient *http.Client | |||||
HOST string | |||||
TOKEN string | |||||
) | |||||
const ( | |||||
errorCodeExceedLimit = "ModelArts.0118" | |||||
//notebook 2.0 | |||||
urlNotebook2 = "/notebooks" | |||||
//error code | |||||
modelartsIllegalToken = "ModelArts.6401" | |||||
NotebookNotFound = "ModelArts.6404" | |||||
NotebookNoPermission = "ModelArts.6407" | |||||
NotebookInvalid = "ModelArts.6400" | |||||
UnknownErrorPrefix = "UNKNOWN:" | |||||
) | |||||
func getHttpClient() *http.Client { | |||||
if httpClient == nil { | |||||
httpClient = &http.Client{ | |||||
Timeout: 30 * time.Second, | |||||
Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}, | |||||
} | |||||
} | |||||
return httpClient | |||||
} | |||||
func GetNotebook(jobID string) (*models.GetNotebook2Result, error) { | |||||
var result models.GetNotebook2Result | |||||
client := getHttpClient() | |||||
s := core.Signer{ | |||||
Key: setting.ModelartsCD.AccessKey, | |||||
Secret: setting.ModelartsCD.SecretKey, | |||||
} | |||||
r, _ := http.NewRequest(http.MethodGet, | |||||
setting.ModelartsCD.EndPoint+"/v1/"+setting.ModelartsCD.ProjectID+urlNotebook2+"/"+jobID, | |||||
nil) | |||||
r.Header.Add("content-type", "application/json") | |||||
s.Sign(r) | |||||
resp, err := client.Do(r) | |||||
if err != nil { | |||||
log.Error("client.Do failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("client.Do failed: %s", err.Error()) | |||||
} | |||||
defer resp.Body.Close() | |||||
body, err := ioutil.ReadAll(resp.Body) | |||||
if err != nil { | |||||
log.Error("ioutil.ReadAll failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("ioutil.ReadAll failed: %s", err.Error()) | |||||
} | |||||
err = json.Unmarshal(body, &result) | |||||
if err != nil { | |||||
log.Error("json.Unmarshal failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("son.Unmarshal failed: %s", err.Error()) | |||||
} | |||||
if len(result.ErrorCode) != 0 { | |||||
log.Error("GetNotebook failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
return &result, fmt.Errorf("GetNotebook failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
} | |||||
return &result, nil | |||||
} | |||||
func ManageNotebook(jobID string, param models.NotebookAction) (*models.NotebookActionResult, error) { | |||||
var result models.NotebookActionResult | |||||
client := getHttpClient() | |||||
s := core.Signer{ | |||||
Key: setting.ModelartsCD.AccessKey, | |||||
Secret: setting.ModelartsCD.SecretKey, | |||||
} | |||||
r, _ := http.NewRequest(http.MethodPost, | |||||
setting.ModelartsCD.EndPoint+"/v1/"+setting.ModelartsCD.ProjectID+urlNotebook2+"/"+jobID+"/"+param.Action+"?duration="+strconv.Itoa(autoStopDurationMs), | |||||
nil) | |||||
r.Header.Add("content-type", "application/json") | |||||
s.Sign(r) | |||||
resp, err := client.Do(r) | |||||
if err != nil { | |||||
log.Error("client.Do failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("client.Do failed: %s", err.Error()) | |||||
} | |||||
defer resp.Body.Close() | |||||
body, err := ioutil.ReadAll(resp.Body) | |||||
if err != nil { | |||||
log.Error("ioutil.ReadAll failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("ioutil.ReadAll failed: %s", err.Error()) | |||||
} | |||||
err = json.Unmarshal(body, &result) | |||||
if err != nil { | |||||
log.Error("json.Unmarshal failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("son.Unmarshal failed: %s", err.Error()) | |||||
} | |||||
if len(result.ErrorCode) != 0 { | |||||
log.Error("ManageNotebook2 failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
return &result, fmt.Errorf("ManageNotebook failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
} | |||||
return &result, nil | |||||
} | |||||
func DelNotebook(jobID string) (*models.NotebookDelResult, error) { | |||||
var result models.NotebookDelResult | |||||
client := getHttpClient() | |||||
s := core.Signer{ | |||||
Key: setting.ModelartsCD.AccessKey, | |||||
Secret: setting.ModelartsCD.SecretKey, | |||||
} | |||||
r, _ := http.NewRequest(http.MethodDelete, | |||||
setting.ModelartsCD.EndPoint+"/v1/"+setting.ModelartsCD.ProjectID+urlNotebook2+"/"+jobID, | |||||
nil) | |||||
r.Header.Add("content-type", "application/json") | |||||
s.Sign(r) | |||||
resp, err := client.Do(r) | |||||
if err != nil { | |||||
log.Error("client.Do failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("client.Do failed: %s", err.Error()) | |||||
} | |||||
defer resp.Body.Close() | |||||
body, err := ioutil.ReadAll(resp.Body) | |||||
if err != nil { | |||||
log.Error("ioutil.ReadAll failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("ioutil.ReadAll failed: %s", err.Error()) | |||||
} | |||||
err = json.Unmarshal(body, &result) | |||||
if err != nil { | |||||
log.Error("json.Unmarshal failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("son.Unmarshal failed: %s", err.Error()) | |||||
} | |||||
if len(result.ErrorCode) != 0 { | |||||
log.Error("DelNotebook2 failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
return &result, fmt.Errorf("DelNotebook2 failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
} | |||||
return &result, nil | |||||
} | |||||
func createNotebook(createJobParams models.CreateNotebookWithoutPoolParams) (*models.CreateNotebookResult, error) { | |||||
var result models.CreateNotebookResult | |||||
client := getHttpClient() | |||||
s := core.Signer{ | |||||
Key: setting.ModelartsCD.AccessKey, | |||||
Secret: setting.ModelartsCD.SecretKey, | |||||
} | |||||
req, _ := json.Marshal(createJobParams) | |||||
r, _ := http.NewRequest(http.MethodPost, | |||||
setting.ModelartsCD.EndPoint+"/v1/"+setting.ModelartsCD.ProjectID+urlNotebook2, | |||||
ioutil.NopCloser(bytes.NewBuffer(req))) | |||||
r.Header.Add("content-type", "application/json") | |||||
s.Sign(r) | |||||
resp, err := client.Do(r) | |||||
if err != nil { | |||||
log.Error("client.Do failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("client.Do failed: %s", err.Error()) | |||||
} | |||||
defer resp.Body.Close() | |||||
body, err := ioutil.ReadAll(resp.Body) | |||||
if err != nil { | |||||
log.Error("ioutil.ReadAll failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("ioutil.ReadAll failed: %s", err.Error()) | |||||
} | |||||
err = json.Unmarshal(body, &result) | |||||
if err != nil { | |||||
log.Error("json.Unmarshal failed: %s", err.Error()) | |||||
return &result, fmt.Errorf("json.Unmarshal failed: %s", err.Error()) | |||||
} | |||||
if len(result.ErrorCode) != 0 { | |||||
log.Error("createNotebook failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
if result.ErrorCode == errorCodeExceedLimit { | |||||
result.ErrorMsg = "所选规格使用数量已超过最大配额限制。" | |||||
} | |||||
return &result, fmt.Errorf("createNotebook failed(%s): %s", result.ErrorCode, result.ErrorMsg) | |||||
} | |||||
return &result, nil | |||||
} |
@@ -0,0 +1,42 @@ | |||||
// based on https://github.com/golang/go/blob/master/src/net/url/url.go | |||||
// Copyright 2009 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package core | |||||
func shouldEscape(c byte) bool { | |||||
if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c == '-' || c == '~' || c == '.' { | |||||
return false | |||||
} | |||||
return true | |||||
} | |||||
func escape(s string) string { | |||||
hexCount := 0 | |||||
for i := 0; i < len(s); i++ { | |||||
c := s[i] | |||||
if shouldEscape(c) { | |||||
hexCount++ | |||||
} | |||||
} | |||||
if hexCount == 0 { | |||||
return s | |||||
} | |||||
t := make([]byte, len(s)+2*hexCount) | |||||
j := 0 | |||||
for i := 0; i < len(s); i++ { | |||||
switch c := s[i]; { | |||||
case shouldEscape(c): | |||||
t[j] = '%' | |||||
t[j+1] = "0123456789ABCDEF"[c>>4] | |||||
t[j+2] = "0123456789ABCDEF"[c&15] | |||||
j += 3 | |||||
default: | |||||
t[j] = s[i] | |||||
j++ | |||||
} | |||||
} | |||||
return string(t) | |||||
} |
@@ -0,0 +1,208 @@ | |||||
// HWS API Gateway Signature | |||||
// based on https://github.com/datastream/aws/blob/master/signv4.go | |||||
// Copyright (c) 2014, Xianjie | |||||
package core | |||||
import ( | |||||
"bytes" | |||||
"crypto/hmac" | |||||
"crypto/sha256" | |||||
"fmt" | |||||
"io/ioutil" | |||||
"net/http" | |||||
"sort" | |||||
"strings" | |||||
"time" | |||||
) | |||||
const ( | |||||
BasicDateFormat = "20060102T150405Z" | |||||
Algorithm = "SDK-HMAC-SHA256" | |||||
HeaderXDate = "X-Sdk-Date" | |||||
HeaderHost = "host" | |||||
HeaderAuthorization = "Authorization" | |||||
HeaderContentSha256 = "X-Sdk-Content-Sha256" | |||||
) | |||||
func hmacsha256(key []byte, data string) ([]byte, error) { | |||||
h := hmac.New(sha256.New, []byte(key)) | |||||
if _, err := h.Write([]byte(data)); err != nil { | |||||
return nil, err | |||||
} | |||||
return h.Sum(nil), nil | |||||
} | |||||
// Build a CanonicalRequest from a regular request string | |||||
// | |||||
// CanonicalRequest = | |||||
// HTTPRequestMethod + '\n' + | |||||
// CanonicalURI + '\n' + | |||||
// CanonicalQueryString + '\n' + | |||||
// CanonicalHeaders + '\n' + | |||||
// SignedHeaders + '\n' + | |||||
// HexEncode(Hash(RequestPayload)) | |||||
func CanonicalRequest(r *http.Request, signedHeaders []string) (string, error) { | |||||
var hexencode string | |||||
var err error | |||||
if hex := r.Header.Get(HeaderContentSha256); hex != "" { | |||||
hexencode = hex | |||||
} else { | |||||
data, err := RequestPayload(r) | |||||
if err != nil { | |||||
return "", err | |||||
} | |||||
hexencode, err = HexEncodeSHA256Hash(data) | |||||
if err != nil { | |||||
return "", err | |||||
} | |||||
} | |||||
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", r.Method, CanonicalURI(r), CanonicalQueryString(r), CanonicalHeaders(r, signedHeaders), strings.Join(signedHeaders, ";"), hexencode), err | |||||
} | |||||
// CanonicalURI returns request uri | |||||
func CanonicalURI(r *http.Request) string { | |||||
pattens := strings.Split(r.URL.Path, "/") | |||||
var uri []string | |||||
for _, v := range pattens { | |||||
uri = append(uri, escape(v)) | |||||
} | |||||
urlpath := strings.Join(uri, "/") | |||||
if len(urlpath) == 0 || urlpath[len(urlpath)-1] != '/' { | |||||
urlpath = urlpath + "/" | |||||
} | |||||
return urlpath | |||||
} | |||||
// CanonicalQueryString | |||||
func CanonicalQueryString(r *http.Request) string { | |||||
var keys []string | |||||
query := r.URL.Query() | |||||
for key := range query { | |||||
keys = append(keys, key) | |||||
} | |||||
sort.Strings(keys) | |||||
var a []string | |||||
for _, key := range keys { | |||||
k := escape(key) | |||||
sort.Strings(query[key]) | |||||
for _, v := range query[key] { | |||||
kv := fmt.Sprintf("%s=%s", k, escape(v)) | |||||
a = append(a, kv) | |||||
} | |||||
} | |||||
queryStr := strings.Join(a, "&") | |||||
r.URL.RawQuery = queryStr | |||||
return queryStr | |||||
} | |||||
// CanonicalHeaders | |||||
func CanonicalHeaders(r *http.Request, signerHeaders []string) string { | |||||
var a []string | |||||
header := make(map[string][]string) | |||||
for k, v := range r.Header { | |||||
header[strings.ToLower(k)] = v | |||||
} | |||||
for _, key := range signerHeaders { | |||||
value := header[key] | |||||
if strings.EqualFold(key, HeaderHost) { | |||||
value = []string{r.Host} | |||||
} | |||||
sort.Strings(value) | |||||
for _, v := range value { | |||||
a = append(a, key+":"+strings.TrimSpace(v)) | |||||
} | |||||
} | |||||
return fmt.Sprintf("%s\n", strings.Join(a, "\n")) | |||||
} | |||||
// SignedHeaders | |||||
func SignedHeaders(r *http.Request) []string { | |||||
var a []string | |||||
for key := range r.Header { | |||||
a = append(a, strings.ToLower(key)) | |||||
} | |||||
sort.Strings(a) | |||||
return a | |||||
} | |||||
// RequestPayload | |||||
func RequestPayload(r *http.Request) ([]byte, error) { | |||||
if r.Body == nil { | |||||
return []byte(""), nil | |||||
} | |||||
b, err := ioutil.ReadAll(r.Body) | |||||
if err != nil { | |||||
return []byte(""), err | |||||
} | |||||
r.Body = ioutil.NopCloser(bytes.NewBuffer(b)) | |||||
return b, err | |||||
} | |||||
// Create a "String to Sign". | |||||
func StringToSign(canonicalRequest string, t time.Time) (string, error) { | |||||
hash := sha256.New() | |||||
_, err := hash.Write([]byte(canonicalRequest)) | |||||
if err != nil { | |||||
return "", err | |||||
} | |||||
return fmt.Sprintf("%s\n%s\n%x", | |||||
Algorithm, t.UTC().Format(BasicDateFormat), hash.Sum(nil)), nil | |||||
} | |||||
// Create the HWS Signature. | |||||
func SignStringToSign(stringToSign string, signingKey []byte) (string, error) { | |||||
hm, err := hmacsha256(signingKey, stringToSign) | |||||
return fmt.Sprintf("%x", hm), err | |||||
} | |||||
// HexEncodeSHA256Hash returns hexcode of sha256 | |||||
func HexEncodeSHA256Hash(body []byte) (string, error) { | |||||
hash := sha256.New() | |||||
if body == nil { | |||||
body = []byte("") | |||||
} | |||||
_, err := hash.Write(body) | |||||
return fmt.Sprintf("%x", hash.Sum(nil)), err | |||||
} | |||||
// Get the finalized value for the "Authorization" header. The signature parameter is the output from SignStringToSign | |||||
func AuthHeaderValue(signature, accessKey string, signedHeaders []string) string { | |||||
return fmt.Sprintf("%s Access=%s, SignedHeaders=%s, Signature=%s", Algorithm, accessKey, strings.Join(signedHeaders, ";"), signature) | |||||
} | |||||
// Signature HWS meta | |||||
type Signer struct { | |||||
Key string | |||||
Secret string | |||||
} | |||||
// SignRequest set Authorization header | |||||
func (s *Signer) Sign(r *http.Request) error { | |||||
var t time.Time | |||||
var err error | |||||
var dt string | |||||
if dt = r.Header.Get(HeaderXDate); dt != "" { | |||||
t, err = time.Parse(BasicDateFormat, dt) | |||||
} | |||||
if err != nil || dt == "" { | |||||
t = time.Now() | |||||
r.Header.Set(HeaderXDate, t.UTC().Format(BasicDateFormat)) | |||||
} | |||||
signedHeaders := SignedHeaders(r) | |||||
canonicalRequest, err := CanonicalRequest(r, signedHeaders) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
stringToSign, err := StringToSign(canonicalRequest, t) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
signature, err := SignStringToSign(stringToSign, []byte(s.Secret)) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
authValue := AuthHeaderValue(signature, s.Key, signedHeaders) | |||||
r.Header.Set(HeaderAuthorization, authValue) | |||||
return nil | |||||
} |
@@ -75,6 +75,26 @@ type C2NetSqInfos struct { | |||||
C2NetSqInfo []*C2NetSequenceInfo `json:"sequence"` | C2NetSqInfo []*C2NetSequenceInfo `json:"sequence"` | ||||
} | } | ||||
type StFlavorInfos struct { | |||||
FlavorInfo []*FlavorInfo `json:"flavor_info"` | |||||
} | |||||
type FlavorInfo struct { | |||||
Id int `json:"id"` | |||||
Value string `json:"value"` | |||||
Desc string `json:"desc"` | |||||
} | |||||
type StImageInfosModelArts struct { | |||||
ImageInfo []*ImageInfoModelArts `json:"image_info"` | |||||
} | |||||
type ImageInfoModelArts struct { | |||||
Id string `json:"id"` | |||||
Value string `json:"value"` | |||||
Desc string `json:"desc"` | |||||
} | |||||
var ( | var ( | ||||
// AppVer settings | // AppVer settings | ||||
AppVer string | AppVer string | ||||
@@ -535,18 +555,31 @@ var ( | |||||
AllowedOrg string | AllowedOrg string | ||||
ProfileID string | ProfileID string | ||||
PoolInfos string | PoolInfos string | ||||
Flavor string | |||||
FlavorInfos string | |||||
DebugHost string | DebugHost string | ||||
ImageInfos string | ImageInfos string | ||||
Capacity int | Capacity int | ||||
MaxTempQueryTimes int | MaxTempQueryTimes int | ||||
StFlavorInfo *StFlavorInfos | |||||
StImageInfos *StImageInfosModelArts | |||||
//train-job | //train-job | ||||
ResourcePools string | ResourcePools string | ||||
Engines string | Engines string | ||||
EngineVersions string | EngineVersions string | ||||
FlavorInfos string | |||||
TrainJobFLAVORINFOS string | TrainJobFLAVORINFOS string | ||||
ModelArtsSpecialPools string | ModelArtsSpecialPools string | ||||
ModelArtsMultiNode string | |||||
// modelarts-cd config | |||||
ModelartsCD = struct { | |||||
Enabled bool | |||||
EndPoint string | |||||
ProjectID string | |||||
AccessKey string | |||||
SecretKey string | |||||
ImageInfos string | |||||
FlavorInfos string | |||||
}{} | |||||
//grampus config | //grampus config | ||||
Grampus = struct { | Grampus = struct { | ||||
@@ -1422,9 +1455,8 @@ func NewContext() { | |||||
AllowedOrg = sec.Key("ORGANIZATION").MustString("") | AllowedOrg = sec.Key("ORGANIZATION").MustString("") | ||||
ProfileID = sec.Key("PROFILE_ID").MustString("") | ProfileID = sec.Key("PROFILE_ID").MustString("") | ||||
PoolInfos = sec.Key("POOL_INFOS").MustString("") | PoolInfos = sec.Key("POOL_INFOS").MustString("") | ||||
Flavor = sec.Key("FLAVOR").MustString("") | |||||
ImageInfos = sec.Key("IMAGE_INFOS").MustString("") | ImageInfos = sec.Key("IMAGE_INFOS").MustString("") | ||||
Capacity = sec.Key("IMAGE_INFOS").MustInt(100) | |||||
Capacity = sec.Key("CAPACITY").MustInt(100) | |||||
MaxTempQueryTimes = sec.Key("MAX_TEMP_QUERY_TIMES").MustInt(30) | MaxTempQueryTimes = sec.Key("MAX_TEMP_QUERY_TIMES").MustInt(30) | ||||
ResourcePools = sec.Key("Resource_Pools").MustString("") | ResourcePools = sec.Key("Resource_Pools").MustString("") | ||||
Engines = sec.Key("Engines").MustString("") | Engines = sec.Key("Engines").MustString("") | ||||
@@ -1432,6 +1464,7 @@ func NewContext() { | |||||
FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | ||||
TrainJobFLAVORINFOS = sec.Key("TrainJob_FLAVOR_INFOS").MustString("") | TrainJobFLAVORINFOS = sec.Key("TrainJob_FLAVOR_INFOS").MustString("") | ||||
ModelArtsSpecialPools = sec.Key("SPECIAL_POOL").MustString("") | ModelArtsSpecialPools = sec.Key("SPECIAL_POOL").MustString("") | ||||
ModelArtsMultiNode=sec.Key("MULTI_NODE").MustString("") | |||||
sec = Cfg.Section("elk") | sec = Cfg.Section("elk") | ||||
ElkUrl = sec.Key("ELKURL").MustString("") | ElkUrl = sec.Key("ELKURL").MustString("") | ||||
@@ -1460,7 +1493,7 @@ func NewContext() { | |||||
CloudbrainStartedRemark = sec.Key("CLOUDBRAIN_STARTED_REMARK").MustString("感谢您的耐心等待。") | CloudbrainStartedRemark = sec.Key("CLOUDBRAIN_STARTED_REMARK").MustString("感谢您的耐心等待。") | ||||
CloudbrainStoppedTemplateId = sec.Key("CLOUDBRAIN_STOPPED_TEMPLATE_ID").MustString("") | CloudbrainStoppedTemplateId = sec.Key("CLOUDBRAIN_STOPPED_TEMPLATE_ID").MustString("") | ||||
CloudbrainStoppedNotifyList = strings.Split(sec.Key("CLOUDBRAIN_STOPPED_NOTIFY_LIST").MustString("TRAIN"), ",") | CloudbrainStoppedNotifyList = strings.Split(sec.Key("CLOUDBRAIN_STOPPED_NOTIFY_LIST").MustString("TRAIN"), ",") | ||||
CloudbrainStoppedTitle = sec.Key("CLOUDBRAIN_STOPPED_TITLE").MustString("您好,您申请的算力资源已结束使用,任务已完成运行,请您关注运行结果。") | |||||
CloudbrainStoppedTitle = sec.Key("CLOUDBRAIN_STOPPED_TITLE").MustString("您好,您申请的算力资源已结束使用,任务已完成运行,状态为%s,请您关注运行结果") | |||||
CloudbrainStoppedRemark = sec.Key("CLOUDBRAIN_STOPPED_REMARK").MustString("感谢您的耐心等待。") | CloudbrainStoppedRemark = sec.Key("CLOUDBRAIN_STOPPED_REMARK").MustString("感谢您的耐心等待。") | ||||
SetRadarMapConfig() | SetRadarMapConfig() | ||||
@@ -1472,8 +1505,8 @@ func NewContext() { | |||||
Course.OrgName = sec.Key("org_name").MustString("") | Course.OrgName = sec.Key("org_name").MustString("") | ||||
Course.TeamName = sec.Key("team_name").MustString("") | Course.TeamName = sec.Key("team_name").MustString("") | ||||
GetGrampusConfig() | |||||
getGrampusConfig() | |||||
getModelartsCDConfig() | |||||
getModelConvertConfig() | getModelConvertConfig() | ||||
} | } | ||||
@@ -1496,7 +1529,22 @@ func getModelConvertConfig() { | |||||
ModelConvert.NPU_TENSORFLOW_IMAGE_ID = sec.Key("NPU_TENSORFLOW_IMAGE_ID").MustInt(35) | ModelConvert.NPU_TENSORFLOW_IMAGE_ID = sec.Key("NPU_TENSORFLOW_IMAGE_ID").MustInt(35) | ||||
} | } | ||||
func GetGrampusConfig() { | |||||
func getModelartsCDConfig() { | |||||
sec := Cfg.Section("modelarts-cd") | |||||
ModelartsCD.Enabled = sec.Key("ENABLED").MustBool(false) | |||||
ModelartsCD.EndPoint = sec.Key("ENDPOINT").MustString("https://modelarts.cn-southwest-228.cdzs.cn") | |||||
ModelartsCD.ProjectID = sec.Key("PROJECT_ID").MustString("") | |||||
ModelartsCD.AccessKey = sec.Key("ACCESS_KEY").MustString("") | |||||
ModelartsCD.SecretKey = sec.Key("SECRET_KEY").MustString("") | |||||
ModelartsCD.ImageInfos = sec.Key("IMAGE_INFOS").MustString("") | |||||
ModelartsCD.FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | |||||
getNotebookImageInfos() | |||||
getNotebookFlavorInfos() | |||||
} | |||||
func getGrampusConfig() { | |||||
sec := Cfg.Section("grampus") | sec := Cfg.Section("grampus") | ||||
Grampus.Env = sec.Key("ENV").MustString("TEST") | Grampus.Env = sec.Key("ENV").MustString("TEST") | ||||
@@ -1630,6 +1678,26 @@ func ensureLFSDirectory() { | |||||
} | } | ||||
} | } | ||||
func getNotebookImageInfos() { | |||||
if StImageInfos == nil { | |||||
if ModelartsCD.Enabled { | |||||
json.Unmarshal([]byte(ModelartsCD.ImageInfos), &StImageInfos) | |||||
} else { | |||||
json.Unmarshal([]byte(ImageInfos), &StImageInfos) | |||||
} | |||||
} | |||||
} | |||||
func getNotebookFlavorInfos() { | |||||
if StFlavorInfo == nil { | |||||
if ModelartsCD.Enabled { | |||||
json.Unmarshal([]byte(ModelartsCD.FlavorInfos), &StFlavorInfo) | |||||
} else { | |||||
json.Unmarshal([]byte(FlavorInfos), &StFlavorInfo) | |||||
} | |||||
} | |||||
} | |||||
// NewServices initializes the services | // NewServices initializes the services | ||||
func NewServices() { | func NewServices() { | ||||
InitDBConfig() | InitDBConfig() | ||||
@@ -1079,6 +1079,7 @@ balance.total_view = Total Balance | |||||
balance.available = Available Balance: | balance.available = Available Balance: | ||||
cloudbrain1 = cloudbrain1 | cloudbrain1 = cloudbrain1 | ||||
cloudbrain2 = cloudbrain2 | cloudbrain2 = cloudbrain2 | ||||
cdCenter = cd_ai_center | |||||
cloudbrain_selection = select cloudbrain | cloudbrain_selection = select cloudbrain | ||||
cloudbrain_platform_selection = Select the cloudbrain platform you want to use: | cloudbrain_platform_selection = Select the cloudbrain platform you want to use: | ||||
confirm_choice = Confirm | confirm_choice = Confirm | ||||
@@ -1213,6 +1214,7 @@ modelarts.infer_job.select_model = Select Model | |||||
modelarts.infer_job.boot_file_helper=The startup file is the entry file for your program execution and must end in.py.Such as inference.py, main.py, example/inference.py, case/main.py. | modelarts.infer_job.boot_file_helper=The startup file is the entry file for your program execution and must end in.py.Such as inference.py, main.py, example/inference.py, case/main.py. | ||||
modelarts.infer_job.tooltip = The model has been deleted and cannot be viewed. | modelarts.infer_job.tooltip = The model has been deleted and cannot be viewed. | ||||
modelarts.download_log=Download log file | modelarts.download_log=Download log file | ||||
modelarts.no_node_right = The value of 'Amount of Compute Node' is wrong, you have no right to use the current value of 'Amount of Compute Node'. | |||||
debug_task_not_created = Debug task has not been created | debug_task_not_created = Debug task has not been created | ||||
@@ -3205,6 +3207,9 @@ gpu_num = GPU | |||||
cpu_num = CPU | cpu_num = CPU | ||||
memory = Memory | memory = Memory | ||||
shared_memory = Shared Memory | shared_memory = Shared Memory | ||||
gpu_memory = GPU Memory | |||||
free = Free | |||||
point_hr = Point/hr | |||||
DEBUG = DEBUG | DEBUG = DEBUG | ||||
@@ -1080,6 +1080,7 @@ balance.total_view=余额总览 | |||||
balance.available=可用余额: | balance.available=可用余额: | ||||
cloudbrain1=云脑1 | cloudbrain1=云脑1 | ||||
cloudbrain2=云脑2 | cloudbrain2=云脑2 | ||||
cdCenter=成都智算中心 | |||||
intelligent_net=智算网络 | intelligent_net=智算网络 | ||||
cloudbrain_selection=云脑选择 | cloudbrain_selection=云脑选择 | ||||
cloudbrain_platform_selection=选择您准备使用的云脑平台: | cloudbrain_platform_selection=选择您准备使用的云脑平台: | ||||
@@ -1226,6 +1227,7 @@ modelarts.infer_job.select_model = 选择模型 | |||||
modelarts.infer_job.boot_file_helper=启动文件是您程序执行的入口文件,必须是以.py结尾的文件。比如inference.py、main.py、example/inference.py、case/main.py。 | modelarts.infer_job.boot_file_helper=启动文件是您程序执行的入口文件,必须是以.py结尾的文件。比如inference.py、main.py、example/inference.py、case/main.py。 | ||||
modelarts.infer_job.tooltip = 该模型已删除,无法查看。 | modelarts.infer_job.tooltip = 该模型已删除,无法查看。 | ||||
modelarts.download_log=下载日志文件 | modelarts.download_log=下载日志文件 | ||||
modelarts.no_node_right = 计算节点数的值配置错误,您没有权限使用当前配置的计算节点数。 | |||||
debug_task_not_created = 未创建过调试任务 | debug_task_not_created = 未创建过调试任务 | ||||
@@ -3224,6 +3226,9 @@ gpu_num = GPU数 | |||||
cpu_num = CPU数 | cpu_num = CPU数 | ||||
memory = 内存 | memory = 内存 | ||||
shared_memory = 共享内存 | shared_memory = 共享内存 | ||||
gpu_memory = 显存 | |||||
free = 免费 | |||||
point_hr = 积分/时 | |||||
DEBUG = 调试任务 | DEBUG = 调试任务 | ||||
SNN4IMAGENET = 评测任务 | SNN4IMAGENET = 评测任务 | ||||
@@ -92,13 +92,13 @@ func CloudBrains(ctx *context.Context) { | |||||
return | return | ||||
} | } | ||||
models.LoadSpecs4CloudbrainInfo(ciTasks) | |||||
for i, task := range ciTasks { | for i, task := range ciTasks { | ||||
ciTasks[i].CanDebug = true | ciTasks[i].CanDebug = true | ||||
ciTasks[i].CanDel = true | ciTasks[i].CanDel = true | ||||
ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | ||||
ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) | ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) | ||||
_, cardType, _ := repo.GetCloudbrainCardNumAndType(task.Cloudbrain) | |||||
ciTasks[i].Cloudbrain.CardType = cardType | |||||
ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) | ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) | ||||
} | } | ||||
@@ -8,6 +8,8 @@ import ( | |||||
"code.gitea.io/gitea/routers/response" | "code.gitea.io/gitea/routers/response" | ||||
"code.gitea.io/gitea/services/cloudbrain/resource" | "code.gitea.io/gitea/services/cloudbrain/resource" | ||||
"net/http" | "net/http" | ||||
"strconv" | |||||
"strings" | |||||
) | ) | ||||
const ( | const ( | ||||
@@ -118,11 +120,13 @@ func GetResourceSpecificationList(ctx *context.Context) { | |||||
queue := ctx.QueryInt64("queue") | queue := ctx.QueryInt64("queue") | ||||
status := ctx.QueryInt("status") | status := ctx.QueryInt("status") | ||||
cluster := ctx.Query("cluster") | cluster := ctx.Query("cluster") | ||||
available := ctx.QueryInt("available") | |||||
list, err := resource.GetResourceSpecificationList(models.SearchResourceSpecificationOptions{ | 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 { | if err != nil { | ||||
log.Error("GetResourceSpecificationList error.%v", err) | log.Error("GetResourceSpecificationList error.%v", err) | ||||
@@ -246,3 +250,37 @@ func UpdateResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||||
} | } | ||||
ctx.JSON(http.StatusOK, response.Success()) | 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)) | |||||
} |
@@ -405,46 +405,83 @@ func CloudbrainDownloadLogFile(ctx *context.Context) { | |||||
func CloudbrainGetLog(ctx *context.Context) { | func CloudbrainGetLog(ctx *context.Context) { | ||||
ID := ctx.Params(":id") | ID := ctx.Params(":id") | ||||
startLine := ctx.QueryInt("base_line") | |||||
lines := ctx.QueryInt("lines") | |||||
endLine := startLine + lines | |||||
order := ctx.Query("order") | |||||
if order == "asc" { | |||||
endLine = startLine | |||||
startLine = endLine - lines | |||||
if startLine < 0 { | |||||
startLine = 0 | |||||
} | |||||
} | |||||
job, err := models.GetCloudbrainByID(ID) | job, err := models.GetCloudbrainByID(ID) | ||||
if err != nil { | if err != nil { | ||||
log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | ||||
ctx.ServerError(err.Error(), err) | ctx.ServerError(err.Error(), err) | ||||
return | return | ||||
} | } | ||||
result := getLogFromModelDir(job.JobName, startLine, endLine) | |||||
if result == nil { | |||||
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"]) | |||||
ctx.ServerError(err.Error(), err) | |||||
return | |||||
lines := ctx.QueryInt("lines") | |||||
baseLine := ctx.Query("base_line") | |||||
order := ctx.Query("order") | |||||
var result map[string]interface{} | |||||
resultPath := "/model" | |||||
if job.JobType == string(models.JobTypeInference) { | |||||
resultPath = "/result" | |||||
} | |||||
if baseLine == "" && order == "desc" { | |||||
result = getLastLogFromModelDir(job.JobName, lines, resultPath) | |||||
} else { | |||||
startLine := ctx.QueryInt("base_line") | |||||
endLine := startLine + lines | |||||
if order == "asc" { | |||||
if baseLine == "" { | |||||
startLine = 0 | |||||
endLine = lines | |||||
} else { | |||||
endLine = startLine | |||||
startLine = endLine - lines | |||||
if startLine < 0 { | |||||
startLine = 0 | |||||
} | |||||
} | |||||
} | |||||
result = getLogFromModelDir(job.JobName, startLine, endLine, resultPath) | |||||
if result == nil { | |||||
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"]) | |||||
ctx.ServerError(err.Error(), err) | |||||
return | |||||
} | |||||
} | } | ||||
re := map[string]interface{}{ | re := map[string]interface{}{ | ||||
"JobID": ID, | "JobID": ID, | ||||
"LogFileName": result["FileName"], | "LogFileName": result["FileName"], | ||||
"StartLine": startLine, | |||||
"EndLine": result["endLine"], | |||||
"StartLine": result["StartLine"], | |||||
"EndLine": result["EndLine"], | |||||
"Content": result["Content"], | "Content": result["Content"], | ||||
"Lines": result["lines"], | |||||
"Lines": result["Lines"], | |||||
"CanLogDownload": result["FileName"] != "", | "CanLogDownload": result["FileName"] != "", | ||||
} | } | ||||
//result := CloudbrainGetLogByJobId(job.JobID, job.JobName) | //result := CloudbrainGetLogByJobId(job.JobID, job.JobName) | ||||
ctx.JSON(http.StatusOK, re) | ctx.JSON(http.StatusOK, re) | ||||
} | } | ||||
func getLogFromModelDir(jobName string, startLine int, endLine int) map[string]interface{} { | |||||
prefix := "/" + setting.CBCodePathPrefix + jobName + "/model" | |||||
func getAllLineFromFile(path string) int { | |||||
count := 0 | |||||
reader, err := os.Open(path) | |||||
defer reader.Close() | |||||
if err == nil { | |||||
r := bufio.NewReader(reader) | |||||
for { | |||||
_, error := r.ReadString('\n') | |||||
if error == io.EOF { | |||||
log.Info("read file completed.") | |||||
break | |||||
} | |||||
if error != nil { | |||||
log.Info("read file error." + error.Error()) | |||||
break | |||||
} | |||||
count = count + 1 | |||||
} | |||||
} else { | |||||
log.Info("error:" + err.Error()) | |||||
} | |||||
return count | |||||
} | |||||
func getLastLogFromModelDir(jobName string, lines int, resultPath string) map[string]interface{} { | |||||
prefix := "/" + setting.CBCodePathPrefix + jobName + resultPath | |||||
files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | ||||
if err != nil { | if err != nil { | ||||
log.Error("query cloudbrain model failed: %v", err) | log.Error("query cloudbrain model failed: %v", err) | ||||
@@ -454,11 +491,81 @@ func getLogFromModelDir(jobName string, startLine int, endLine int) map[string]i | |||||
re := "" | re := "" | ||||
fileName := "" | fileName := "" | ||||
count := 0 | count := 0 | ||||
allLines := 0 | |||||
startLine := 0 | |||||
for _, file := range files { | |||||
if strings.HasSuffix(file.FileName, "log.txt") { | |||||
fileName = file.FileName | |||||
path := storage.GetMinioPath(jobName+resultPath+"/", file.FileName) | |||||
allLines = getAllLineFromFile(path) | |||||
startLine = allLines - lines | |||||
if startLine < 0 { | |||||
startLine = 0 | |||||
} | |||||
count = allLines - startLine | |||||
log.Info("path=" + path) | |||||
reader, err := os.Open(path) | |||||
defer reader.Close() | |||||
if err == nil { | |||||
r := bufio.NewReader(reader) | |||||
for i := 0; i < allLines; i++ { | |||||
line, error := r.ReadString('\n') | |||||
if error == io.EOF { | |||||
log.Info("read file completed.") | |||||
break | |||||
} | |||||
if error != nil { | |||||
log.Info("read file error." + error.Error()) | |||||
break | |||||
} | |||||
if error == nil { | |||||
if i >= startLine { | |||||
re = re + line | |||||
} | |||||
} | |||||
} | |||||
} else { | |||||
log.Info("error:" + err.Error()) | |||||
} | |||||
break | |||||
} | |||||
} | |||||
return map[string]interface{}{ | |||||
"JobName": jobName, | |||||
"Content": re, | |||||
"FileName": fileName, | |||||
"Lines": count, | |||||
"EndLine": allLines, | |||||
"StartLine": startLine, | |||||
} | |||||
} | |||||
func getLogFromModelDir(jobName string, startLine int, endLine int, resultPath string) map[string]interface{} { | |||||
prefix := "/" + setting.CBCodePathPrefix + jobName + resultPath | |||||
files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | |||||
if err != nil { | |||||
log.Error("query cloudbrain model failed: %v", err) | |||||
return nil | |||||
} | |||||
if startLine == endLine { | |||||
return map[string]interface{}{ | |||||
"JobName": jobName, | |||||
"Content": "", | |||||
"FileName": "", | |||||
"Lines": 0, | |||||
"EndLine": startLine, | |||||
"StartLine": startLine, | |||||
} | |||||
} | |||||
re := "" | |||||
fileName := "" | |||||
count := 0 | |||||
fileEndLine := endLine | fileEndLine := endLine | ||||
for _, file := range files { | for _, file := range files { | ||||
if strings.HasSuffix(file.FileName, "log.txt") { | if strings.HasSuffix(file.FileName, "log.txt") { | ||||
fileName = file.FileName | fileName = file.FileName | ||||
path := storage.GetMinioPath(jobName+"/model/", file.FileName) | |||||
path := storage.GetMinioPath(jobName+resultPath+"/", file.FileName) | |||||
log.Info("path=" + path) | log.Info("path=" + path) | ||||
reader, err := os.Open(path) | reader, err := os.Open(path) | ||||
defer reader.Close() | defer reader.Close() | ||||
@@ -467,7 +574,6 @@ func getLogFromModelDir(jobName string, startLine int, endLine int) map[string]i | |||||
for i := 0; i < endLine; i++ { | for i := 0; i < endLine; i++ { | ||||
line, error := r.ReadString('\n') | line, error := r.ReadString('\n') | ||||
log.Info("line=" + line) | log.Info("line=" + line) | ||||
fileEndLine = i | |||||
if error == io.EOF { | if error == io.EOF { | ||||
log.Info("read file completed.") | log.Info("read file completed.") | ||||
break | break | ||||
@@ -478,11 +584,13 @@ func getLogFromModelDir(jobName string, startLine int, endLine int) map[string]i | |||||
} | } | ||||
if error == nil { | if error == nil { | ||||
if i >= startLine { | if i >= startLine { | ||||
fileEndLine = i | |||||
re = re + line | re = re + line | ||||
count++ | count++ | ||||
} | } | ||||
} | } | ||||
} | } | ||||
fileEndLine = fileEndLine + 1 | |||||
} else { | } else { | ||||
log.Info("error:" + err.Error()) | log.Info("error:" + err.Error()) | ||||
} | } | ||||
@@ -491,11 +599,12 @@ func getLogFromModelDir(jobName string, startLine int, endLine int) map[string]i | |||||
} | } | ||||
return map[string]interface{}{ | return map[string]interface{}{ | ||||
"JobName": jobName, | |||||
"Content": re, | |||||
"FileName": fileName, | |||||
"lines": count, | |||||
"endLine": fileEndLine, | |||||
"JobName": jobName, | |||||
"Content": re, | |||||
"FileName": fileName, | |||||
"Lines": count, | |||||
"EndLine": fileEndLine, | |||||
"StartLine": startLine, | |||||
} | } | ||||
} | } | ||||
@@ -6,6 +6,7 @@ | |||||
package private | package private | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/routers/admin" | |||||
"strings" | "strings" | ||||
"code.gitea.io/gitea/routers/repo" | "code.gitea.io/gitea/routers/repo" | ||||
@@ -51,6 +52,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Get("/tool/org_stat", OrgStatisticManually) | m.Get("/tool/org_stat", OrgStatisticManually) | ||||
m.Post("/tool/update_repo_visit/:date", UpdateRepoVisit) | m.Post("/tool/update_repo_visit/:date", UpdateRepoVisit) | ||||
m.Post("/task/history_handle/duration", repo.HandleTaskWithNoDuration) | m.Post("/task/history_handle/duration", repo.HandleTaskWithNoDuration) | ||||
m.Post("/resources/specification/handle_historical_task", admin.RefreshHistorySpec) | |||||
}, CheckInternalToken) | }, CheckInternalToken) | ||||
} | } |
@@ -2,6 +2,7 @@ package repo | |||||
import ( | import ( | ||||
"bufio" | "bufio" | ||||
"code.gitea.io/gitea/services/cloudbrain/resource" | |||||
"encoding/json" | "encoding/json" | ||||
"errors" | "errors" | ||||
"fmt" | "fmt" | ||||
@@ -121,86 +122,7 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||||
ctx.Data["QueuesDetail"] = queuesDetail | 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["params"] = "" | ||||
ctx.Data["branchName"] = ctx.Repo.BranchName | ctx.Data["branchName"] = ctx.Repo.BranchName | ||||
@@ -218,6 +140,40 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||||
return nil | 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) { | func CloudBrainNew(ctx *context.Context) { | ||||
err := cloudBrainNewDataPrepare(ctx) | err := cloudBrainNewDataPrepare(ctx) | ||||
if err != nil { | if err != nil { | ||||
@@ -235,9 +191,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
image := strings.TrimSpace(form.Image) | image := strings.TrimSpace(form.Image) | ||||
uuids := form.Attachment | uuids := form.Attachment | ||||
jobType := form.JobType | jobType := form.JobType | ||||
gpuQueue := form.GpuType | |||||
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
resourceSpecId := form.ResourceSpecId | |||||
branchName := form.BranchName | branchName := form.BranchName | ||||
bootFile := strings.TrimSpace(form.BootFile) | bootFile := strings.TrimSpace(form.BootFile) | ||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
@@ -325,18 +279,10 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
command = commandTrain | command = commandTrain | ||||
} | } | ||||
errStr := checkCloudBrainSpecialPool(ctx, jobType, gpuQueue, resourceSpecId) | |||||
if errStr != "" { | |||||
cloudBrainNewDataPrepare(ctx) | |||||
ctx.RenderWithErr(errStr, tpl, &form) | |||||
return | |||||
} | |||||
if branchName == "" { | if branchName == "" { | ||||
branchName = cloudbrain.DefaultBranchName | branchName = cloudbrain.DefaultBranchName | ||||
} | } | ||||
errStr = loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ModelMountPath) | |||||
errStr := loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ModelMountPath) | |||||
if errStr != "" { | if errStr != "" { | ||||
cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr(ctx.Tr(errStr), tpl, &form) | 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) | 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{ | req := cloudbrain.GenerateCloudBrainTaskReq{ | ||||
Ctx: ctx, | Ctx: ctx, | ||||
DisplayJobName: displayJobName, | DisplayJobName: displayJobName, | ||||
@@ -360,7 +317,6 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | ||||
JobType: jobType, | JobType: jobType, | ||||
GpuQueue: gpuQueue, | |||||
Description: form.Description, | Description: form.Description, | ||||
BranchName: branchName, | BranchName: branchName, | ||||
BootFile: form.BootFile, | BootFile: form.BootFile, | ||||
@@ -368,8 +324,8 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
CommitID: commitID, | CommitID: commitID, | ||||
BenchmarkTypeID: 0, | BenchmarkTypeID: 0, | ||||
BenchmarkChildTypeID: 0, | BenchmarkChildTypeID: 0, | ||||
ResourceSpecId: resourceSpecId, | |||||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ||||
Spec: spec, | |||||
} | } | ||||
err = cloudbrain.GenerateTask(req) | err = cloudbrain.GenerateTask(req) | ||||
@@ -417,9 +373,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||||
image := strings.TrimSpace(form.Image) | image := strings.TrimSpace(form.Image) | ||||
uuid := form.Attachment | uuid := form.Attachment | ||||
jobType := string(models.JobTypeInference) | jobType := string(models.JobTypeInference) | ||||
gpuQueue := form.GpuType | |||||
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
resourceSpecId := form.ResourceSpecId | |||||
branchName := form.BranchName | branchName := form.BranchName | ||||
bootFile := strings.TrimSpace(form.BootFile) | bootFile := strings.TrimSpace(form.BootFile) | ||||
labelName := form.LabelName | 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) | ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) | ||||
return | 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{ | req := cloudbrain.GenerateCloudBrainTaskReq{ | ||||
Ctx: ctx, | Ctx: ctx, | ||||
DisplayJobName: displayJobName, | DisplayJobName: displayJobName, | ||||
@@ -517,19 +480,18 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||||
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | ||||
JobType: jobType, | JobType: jobType, | ||||
GpuQueue: gpuQueue, | |||||
Description: form.Description, | Description: form.Description, | ||||
BranchName: branchName, | BranchName: branchName, | ||||
BootFile: form.BootFile, | BootFile: form.BootFile, | ||||
Params: form.Params, | Params: form.Params, | ||||
CommitID: commitID, | CommitID: commitID, | ||||
ResourceSpecId: resourceSpecId, | |||||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ||||
ModelName: form.ModelName, | ModelName: form.ModelName, | ||||
ModelVersion: form.ModelVersion, | ModelVersion: form.ModelVersion, | ||||
CkptName: form.CkptName, | CkptName: form.CkptName, | ||||
TrainUrl: form.TrainUrl, | TrainUrl: form.TrainUrl, | ||||
LabelName: labelName, | LabelName: labelName, | ||||
Spec: spec, | |||||
} | } | ||||
err = cloudbrain.GenerateTask(req) | err = cloudbrain.GenerateTask(req) | ||||
@@ -607,34 +569,25 @@ func CloudBrainRestart(ctx *context.Context) { | |||||
break | 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" | resultCode = "-1" | ||||
errorMsg = "the job's version is too old and can not be restarted" | |||||
errorMsg = "Resource specification not support any more" | |||||
break | break | ||||
} | } | ||||
task.Spec = spec | |||||
count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, string(models.JobTypeDebug)) | count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, string(models.JobTypeDebug)) | ||||
if err != nil { | 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) | ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ||||
return | 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 { | if result != nil { | ||||
jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | 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 | taskRoles := jobRes.TaskRoles | ||||
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | ||||
ctx.Data["taskRes"] = taskRes | ctx.Data["taskRes"] = taskRes | ||||
@@ -952,6 +790,85 @@ func CloudBrainDebug(ctx *context.Context) { | |||||
ctx.Redirect(debugUrl) | 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) { | func CloudBrainCommitImageShow(ctx *context.Context) { | ||||
ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
ctx.Data["Type"] = ctx.Cloudbrain.Type | ctx.Data["Type"] = ctx.Cloudbrain.Type | ||||
@@ -2285,10 +2202,8 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||||
displayJobName := form.DisplayJobName | displayJobName := form.DisplayJobName | ||||
jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | ||||
image := strings.TrimSpace(form.Image) | image := strings.TrimSpace(form.Image) | ||||
gpuQueue := form.GpuType | |||||
command := cloudbrain.CommandBenchmark | command := cloudbrain.CommandBenchmark | ||||
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
resourceSpecId := cloudbrain.BenchMarkResourceID | |||||
benchmarkTypeID := form.BenchmarkTypeID | benchmarkTypeID := form.BenchmarkTypeID | ||||
benchmarkChildTypeID := form.BenchmarkChildTypeID | benchmarkChildTypeID := form.BenchmarkChildTypeID | ||||
@@ -2329,19 +2244,14 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||||
return | return | ||||
} | } | ||||
_, err = getBenchmarkGpuQueue(gpuQueue) | |||||
if err != nil { | |||||
log.Error("getBenchmarkGpuQueue failed:%v", err, ctx.Data["MsgID"]) | |||||
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"]) | |||||
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) | cloudBrainNewDataPrepare(ctx) | ||||
ctx.RenderWithErr("resource spec error", tplCloudBrainBenchmarkNew, &form) | |||||
ctx.RenderWithErr("Resource specification not available", tplCloudBrainBenchmarkNew, &form) | |||||
return | return | ||||
} | } | ||||
@@ -2402,14 +2312,8 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||||
} | } | ||||
benchmarkPath := setting.JobPath + jobName + cloudbrain.BenchMarkMountPath | 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"]) | log.Error("downloadRateCode failed, %v", err, ctx.Data["MsgID"]) | ||||
//cloudBrainNewDataPrepare(ctx) | //cloudBrainNewDataPrepare(ctx) | ||||
//ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | //ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | ||||
@@ -2431,7 +2335,8 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||||
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tplCloudBrainBenchmarkNew, &form) | ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tplCloudBrainBenchmarkNew, &form) | ||||
return | return | ||||
} | } | ||||
log.Info("Command=" + command) | |||||
log.Info("ModelPath=" + storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/")) | |||||
req := cloudbrain.GenerateCloudBrainTaskReq{ | req := cloudbrain.GenerateCloudBrainTaskReq{ | ||||
Ctx: ctx, | Ctx: ctx, | ||||
DisplayJobName: displayJobName, | DisplayJobName: displayJobName, | ||||
@@ -2447,7 +2352,6 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||||
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | ||||
JobType: string(models.JobTypeBenchmark), | JobType: string(models.JobTypeBenchmark), | ||||
GpuQueue: gpuQueue, | |||||
Description: form.Description, | Description: form.Description, | ||||
BranchName: cloudbrain.DefaultBranchName, | BranchName: cloudbrain.DefaultBranchName, | ||||
BootFile: "", | BootFile: "", | ||||
@@ -2455,8 +2359,8 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||||
CommitID: "", | CommitID: "", | ||||
BenchmarkTypeID: benchmarkTypeID, | BenchmarkTypeID: benchmarkTypeID, | ||||
BenchmarkChildTypeID: benchmarkChildTypeID, | BenchmarkChildTypeID: benchmarkChildTypeID, | ||||
ResourceSpecId: resourceSpecId, | |||||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ||||
Spec: spec, | |||||
} | } | ||||
err = cloudbrain.GenerateTask(req) | err = cloudbrain.GenerateTask(req) | ||||
@@ -2476,9 +2380,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||||
image := form.Image | image := form.Image | ||||
uuid := form.Attachment | uuid := form.Attachment | ||||
jobType := form.JobType | jobType := form.JobType | ||||
gpuQueue := form.GpuType | |||||
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
resourceSpecId := form.ResourceSpecId | |||||
branchName := cloudbrain.DefaultBranchName | branchName := cloudbrain.DefaultBranchName | ||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
@@ -2560,7 +2462,18 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||||
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) | ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) | ||||
return | return | ||||
} | } | ||||
spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||||
JobType: models.JobTypeBenchmark, | |||||
ComputeResource: models.GPU, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: models.AICenterOfCloudBrainOne}) | |||||
if err != nil || spec == nil { | |||||
cloudBrainNewDataPrepare(ctx) | |||||
ctx.RenderWithErr("Resource specification not available", tpl, &form) | |||||
return | |||||
} | |||||
log.Info("Command=" + command) | |||||
log.Info("ModelPath=" + storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/")) | |||||
req := cloudbrain.GenerateCloudBrainTaskReq{ | req := cloudbrain.GenerateCloudBrainTaskReq{ | ||||
Ctx: ctx, | Ctx: ctx, | ||||
DisplayJobName: displayJobName, | DisplayJobName: displayJobName, | ||||
@@ -2576,7 +2489,6 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||||
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | ||||
JobType: jobType, | JobType: jobType, | ||||
GpuQueue: gpuQueue, | |||||
Description: form.Description, | Description: form.Description, | ||||
BranchName: branchName, | BranchName: branchName, | ||||
BootFile: form.BootFile, | BootFile: form.BootFile, | ||||
@@ -2584,8 +2496,8 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||||
CommitID: "", | CommitID: "", | ||||
BenchmarkTypeID: 0, | BenchmarkTypeID: 0, | ||||
BenchmarkChildTypeID: benchmarkChildTypeID, | BenchmarkChildTypeID: benchmarkChildTypeID, | ||||
ResourceSpecId: resourceSpecId, | |||||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | ||||
Spec: spec, | |||||
} | } | ||||
err = cloudbrain.GenerateTask(req) | err = cloudbrain.GenerateTask(req) | ||||
@@ -2718,7 +2630,7 @@ func getTrainJobCommand(form auth.CreateCloudBrainForm) (string, error) { | |||||
} | } | ||||
} | } | ||||
command += "python /code/" + bootFile + param + " | tee " + cloudbrain.ModelMountPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile | |||||
command += "python /code/" + bootFile + param + " > " + cloudbrain.ModelMountPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile | |||||
return command, nil | return command, nil | ||||
} | } | ||||
@@ -2763,6 +2675,8 @@ func GetCloudbrainAiCenter(task models.Cloudbrain, ctx *context.Context) string | |||||
return ctx.Tr("repo.cloudbrain1") | return ctx.Tr("repo.cloudbrain1") | ||||
} else if task.Type == models.TypeCloudBrainTwo { | } else if task.Type == models.TypeCloudBrainTwo { | ||||
return ctx.Tr("repo.cloudbrain2") | return ctx.Tr("repo.cloudbrain2") | ||||
} else if task.Type == models.TypeCDCenter { | |||||
return ctx.Tr("repo.cdCenter") | |||||
} else if task.Type == models.TypeC2Net { | } else if task.Type == models.TypeC2Net { | ||||
return getCutStringAiCenterByAiCenter(task.AiCenter) | return getCutStringAiCenterByAiCenter(task.AiCenter) | ||||
} | } | ||||
@@ -2777,7 +2691,7 @@ func getCutStringAiCenterByAiCenter(aiCenter string) string { | |||||
} | } | ||||
func GetCloudbrainCluster(task models.Cloudbrain, ctx *context.Context) string { | func GetCloudbrainCluster(task models.Cloudbrain, ctx *context.Context) string { | ||||
if task.Type == models.TypeCloudBrainOne || task.Type == models.TypeCloudBrainTwo { | |||||
if task.Type == models.TypeCloudBrainOne || task.Type == models.TypeCloudBrainTwo || task.Type == models.TypeCDCenter { | |||||
return ctx.Tr("cloudbrain.resource_cluster_openi") | return ctx.Tr("cloudbrain.resource_cluster_openi") | ||||
} else if task.Type == models.TypeC2Net { | } else if task.Type == models.TypeC2Net { | ||||
return ctx.Tr("cloudbrain.resource_cluster_c2net") | return ctx.Tr("cloudbrain.resource_cluster_c2net") | ||||
@@ -2864,10 +2778,10 @@ func GetCloudbrainFlavorName(task models.Cloudbrain) (string, error) { | |||||
return CloudbrainOneFlavorName, nil | return CloudbrainOneFlavorName, nil | ||||
} | } | ||||
} | } | ||||
} else if (task.Type == models.TypeCloudBrainTwo || task.Type == models.TypeC2Net) && task.FlavorName != "" { | |||||
} else if (task.Type == models.TypeCloudBrainTwo || task.Type == models.TypeC2Net || task.Type == models.TypeCDCenter) && task.FlavorName != "" { | |||||
replaceFlavorName := strings.ReplaceAll(task.FlavorName, ":", ":") | replaceFlavorName := strings.ReplaceAll(task.FlavorName, ":", ":") | ||||
return replaceFlavorName, nil | return replaceFlavorName, nil | ||||
} else if task.Type == models.TypeCloudBrainTwo && task.FlavorName == "" && task.FlavorCode != "" { | |||||
} else if (task.Type == models.TypeCloudBrainTwo || task.Type == models.TypeCDCenter) && task.FlavorName == "" && task.FlavorCode != "" { | |||||
cloudbrainTwoFlavorName := getFlavorNameByFlavorCode(task.FlavorCode) | cloudbrainTwoFlavorName := getFlavorNameByFlavorCode(task.FlavorCode) | ||||
return cloudbrainTwoFlavorName, nil | return cloudbrainTwoFlavorName, nil | ||||
} else if task.Type == models.TypeCloudBrainTwo && task.JobType == string(models.JobTypeDebug) && task.FlavorName == "" && task.FlavorCode == "" { | } else if task.Type == models.TypeCloudBrainTwo && task.JobType == string(models.JobTypeDebug) && task.FlavorName == "" && task.FlavorCode == "" { | ||||
@@ -45,15 +45,10 @@ func newFilterPrivateAttachments(ctx *context.Context, list []*models.Attachment | |||||
repo.GetOwner() | repo.GetOwner() | ||||
} | } | ||||
permission := false | permission := false | ||||
if repo.Owner.IsOrganization() && ctx.User != nil { | |||||
if repo.Owner.IsUserPartOfOrg(ctx.User.ID) { | |||||
log.Info("user is member of org.") | |||||
permission = true | |||||
} | |||||
} | |||||
if !permission && ctx.User != nil { | if !permission && ctx.User != nil { | ||||
isCollaborator, _ := repo.IsCollaborator(ctx.User.ID) | isCollaborator, _ := repo.IsCollaborator(ctx.User.ID) | ||||
if isCollaborator { | |||||
isInRepoTeam,_:=repo.IsInRepoTeam(ctx.User.ID) | |||||
if isCollaborator ||isInRepoTeam { | |||||
log.Info("Collaborator user may visit the attach.") | log.Info("Collaborator user may visit the attach.") | ||||
permission = true | permission = true | ||||
} | } | ||||
@@ -1,6 +1,7 @@ | |||||
package repo | package repo | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/services/cloudbrain/resource" | |||||
"encoding/json" | "encoding/json" | ||||
"errors" | "errors" | ||||
"fmt" | "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 | //get branches | ||||
@@ -140,6 +137,15 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err | |||||
return nil | 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 { | func getFilterSpecBySpecialPool(specs *models.GetGrampusResourceSpecsResult, includeCenters map[string]struct{}, excludeCenters map[string]struct{}) []models.GrampusSpec { | ||||
if len(includeCenters) == 0 && len(excludeCenters) == 0 { | if len(includeCenters) == 0 && len(excludeCenters) == 0 { | ||||
return specs.Infos | return specs.Infos | ||||
@@ -206,7 +212,6 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||||
codeMinioPath := setting.CBCodePathPrefix + jobName + cloudbrain.CodeMountPath + "/" | codeMinioPath := setting.CBCodePathPrefix + jobName + cloudbrain.CodeMountPath + "/" | ||||
dataMinioPath := setting.Attachment.Minio.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid | dataMinioPath := setting.Attachment.Minio.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid | ||||
branchName := form.BranchName | branchName := form.BranchName | ||||
flavorName := form.FlavorName | |||||
image := strings.TrimSpace(form.Image) | image := strings.TrimSpace(form.Image) | ||||
if !jobNamePattern.MatchString(displayJobName) { | 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 | //check dataset | ||||
attachment, err := models.GetAttachmentByUUID(uuid) | attachment, err := models.GetAttachmentByUUID(uuid) | ||||
if err != nil { | if err != nil { | ||||
@@ -336,7 +353,6 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||||
ComputeResource: models.GPUResource, | ComputeResource: models.GPUResource, | ||||
ProcessType: grampus.ProcessorTypeGPU, | ProcessType: grampus.ProcessorTypeGPU, | ||||
Command: command, | Command: command, | ||||
ResourceSpecId: form.FlavorID, | |||||
ImageUrl: image, | ImageUrl: image, | ||||
Description: description, | Description: description, | ||||
BootFile: bootFile, | BootFile: bootFile, | ||||
@@ -344,12 +360,12 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||||
CommitID: commitID, | CommitID: commitID, | ||||
BranchName: branchName, | BranchName: branchName, | ||||
Params: form.Params, | Params: form.Params, | ||||
FlavorName: flavorName, | |||||
EngineName: image, | EngineName: image, | ||||
DatasetName: attachment.Name, | DatasetName: attachment.Name, | ||||
IsLatestVersion: modelarts.IsLatestVersion, | IsLatestVersion: modelarts.IsLatestVersion, | ||||
VersionCount: modelarts.VersionCountOne, | VersionCount: modelarts.VersionCountOne, | ||||
WorkServerNumber: 1, | WorkServerNumber: 1, | ||||
Spec: spec, | |||||
} | } | ||||
err = grampus.GenerateTrainJob(ctx, req) | 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 + "/" | dataObsPath := setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/" | ||||
branchName := form.BranchName | branchName := form.BranchName | ||||
isLatestVersion := modelarts.IsLatestVersion | isLatestVersion := modelarts.IsLatestVersion | ||||
flavorName := form.FlavorName | |||||
versionCount := modelarts.VersionCountOne | versionCount := modelarts.VersionCountOne | ||||
engineName := form.EngineName | 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 | //check dataset | ||||
attachment, err := models.GetAttachmentByUUID(uuid) | attachment, err := models.GetAttachmentByUUID(uuid) | ||||
if err != nil { | if err != nil { | ||||
@@ -518,7 +545,6 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||||
ComputeResource: models.NPUResource, | ComputeResource: models.NPUResource, | ||||
ProcessType: grampus.ProcessorTypeNPU, | ProcessType: grampus.ProcessorTypeNPU, | ||||
Command: command, | Command: command, | ||||
ResourceSpecId: form.FlavorID, | |||||
ImageId: form.ImageID, | ImageId: form.ImageID, | ||||
DataUrl: dataObsPath, | DataUrl: dataObsPath, | ||||
Description: description, | Description: description, | ||||
@@ -531,11 +557,11 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||||
IsLatestVersion: isLatestVersion, | IsLatestVersion: isLatestVersion, | ||||
BranchName: branchName, | BranchName: branchName, | ||||
Params: form.Params, | Params: form.Params, | ||||
FlavorName: flavorName, | |||||
EngineName: engineName, | EngineName: engineName, | ||||
VersionCount: versionCount, | VersionCount: versionCount, | ||||
TotalVersionCount: modelarts.TotalVersionCount, | TotalVersionCount: modelarts.TotalVersionCount, | ||||
DatasetName: attachment.Name, | DatasetName: attachment.Name, | ||||
Spec: spec, | |||||
} | } | ||||
err = grampus.GenerateTrainJob(ctx, req) | err = grampus.GenerateTrainJob(ctx, req) | ||||
@@ -712,6 +738,7 @@ func GrampusTrainJobShow(ctx *context.Context) { | |||||
taskList := make([]*models.Cloudbrain, 0) | taskList := make([]*models.Cloudbrain, 0) | ||||
taskList = append(taskList, task) | taskList = append(taskList, task) | ||||
prepareSpec4Show(ctx, task) | |||||
ctx.Data["version_list_task"] = taskList | ctx.Data["version_list_task"] = taskList | ||||
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false) | ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false) | ||||
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | ||||
@@ -2,6 +2,8 @@ package repo | |||||
import ( | import ( | ||||
"archive/zip" | "archive/zip" | ||||
"code.gitea.io/gitea/modules/modelarts_cd" | |||||
"code.gitea.io/gitea/services/cloudbrain/resource" | |||||
"encoding/json" | "encoding/json" | ||||
"errors" | "errors" | ||||
"fmt" | "fmt" | ||||
@@ -60,18 +62,11 @@ func DebugJobIndex(ctx *context.Context) { | |||||
if page <= 0 { | if page <= 0 { | ||||
page = 1 | page = 1 | ||||
} | } | ||||
typeCloudBrain := models.TypeCloudBrainAll | |||||
jobTypeNot := false | jobTypeNot := false | ||||
if listType == models.GPUResource { | |||||
typeCloudBrain = models.TypeCloudBrainOne | |||||
} else if listType == models.NPUResource { | |||||
typeCloudBrain = models.TypeCloudBrainTwo | |||||
} else if listType == models.AllResource { | |||||
typeCloudBrain = models.TypeCloudBrainAll | |||||
} else { | |||||
log.Error("listType(%s) error", listType) | |||||
ctx.ServerError("listType error", errors.New("listType error")) | |||||
return | |||||
var computeResource string | |||||
if listType != models.AllResource { | |||||
computeResource = listType | |||||
} | } | ||||
var jobTypes []string | var jobTypes []string | ||||
@@ -81,10 +76,11 @@ func DebugJobIndex(ctx *context.Context) { | |||||
Page: page, | Page: page, | ||||
PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, | ||||
}, | }, | ||||
RepoID: repo.ID, | |||||
Type: typeCloudBrain, | |||||
JobTypeNot: jobTypeNot, | |||||
JobTypes: jobTypes, | |||||
RepoID: repo.ID, | |||||
ComputeResource: computeResource, | |||||
Type: models.TypeCloudBrainAll, | |||||
JobTypeNot: jobTypeNot, | |||||
JobTypes: jobTypes, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("Get debugjob faild:", err) | ctx.ServerError("Get debugjob faild:", err) | ||||
@@ -134,17 +130,9 @@ func notebookNewDataPrepare(ctx *context.Context) error { | |||||
return err | return err | ||||
} | } | ||||
ctx.Data["attachments"] = attachs | ctx.Data["attachments"] = attachs | ||||
ctx.Data["images"] = setting.StImageInfos.ImageInfo | |||||
if modelarts.ImageInfos == nil { | |||||
json.Unmarshal([]byte(setting.ImageInfos), &modelarts.ImageInfos) | |||||
} | |||||
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 | ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ||||
@@ -154,6 +142,20 @@ func notebookNewDataPrepare(ctx *context.Context) error { | |||||
return nil | return nil | ||||
} | } | ||||
func prepareCloudbrainTwoDebugSpecs(ctx *context.Context) { | |||||
aiCenterCode := models.AICenterOfCloudBrainTwo | |||||
if setting.ModelartsCD.Enabled { | |||||
aiCenterCode = models.AICenterOfChengdu | |||||
} | |||||
noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||||
JobType: models.JobTypeDebug, | |||||
ComputeResource: models.NPU, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: aiCenterCode, | |||||
}) | |||||
ctx.Data["Specs"] = noteBookSpecs | |||||
} | |||||
func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { | func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { | ||||
ctx.Data["PageIsNotebook"] = true | ctx.Data["PageIsNotebook"] = true | ||||
jobName := form.JobName | jobName := form.JobName | ||||
@@ -204,7 +206,6 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||||
jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | ||||
uuid := form.Attachment | uuid := form.Attachment | ||||
description := form.Description | description := form.Description | ||||
flavor := form.Flavor | |||||
imageId := form.ImageId | imageId := form.ImageId | ||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
@@ -239,15 +240,26 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||||
return | return | ||||
} | } | ||||
} | } | ||||
errStr := checkModelArtsSpecialPool(ctx, flavor, string(models.JobTypeDebug)) | |||||
if errStr != "" { | |||||
var aiCenterCode = models.AICenterOfCloudBrainTwo | |||||
if setting.ModelartsCD.Enabled { | |||||
aiCenterCode = models.AICenterOfChengdu | |||||
} | |||||
spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||||
JobType: models.JobTypeDebug, | |||||
ComputeResource: models.NPU, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: aiCenterCode}) | |||||
if err != nil || spec == nil { | |||||
notebookNewDataPrepare(ctx) | notebookNewDataPrepare(ctx) | ||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsNotebookNew, &form) | |||||
ctx.RenderWithErr("Resource specification not available", tplModelArtsNotebookNew, &form) | |||||
return | return | ||||
} | } | ||||
if setting.ModelartsCD.Enabled { | |||||
err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec) | |||||
} else { | |||||
err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec) | |||||
} | |||||
err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, flavor, imageId) | |||||
if err != nil { | if err != nil { | ||||
log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | ||||
notebookNewDataPrepare(ctx) | notebookNewDataPrepare(ctx) | ||||
@@ -292,24 +304,7 @@ func NotebookShow(ctx *context.Context) { | |||||
if err == nil { | if err == nil { | ||||
task.User = user | 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.TrainJobDuration == "" { | ||||
if task.Duration == 0 { | if task.Duration == 0 { | ||||
var duration int64 | var duration int64 | ||||
@@ -394,36 +389,16 @@ func setShowSpecBySpecialPoolConfig(ctx *context.Context, findSpec bool, task *m | |||||
} | } | ||||
} | } | ||||
func NotebookDebug(ctx *context.Context) { | |||||
var jobID = ctx.Params(":jobid") | |||||
result, err := modelarts.GetJob(jobID) | |||||
if err != nil { | |||||
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil) | |||||
return | |||||
} | |||||
res, err := modelarts.GetJobToken(jobID) | |||||
if err != nil { | |||||
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil) | |||||
return | |||||
} | |||||
urls := strings.Split(result.Spec.Annotations.Url, "/") | |||||
urlPrefix := result.Spec.Annotations.TargetDomain | |||||
for i, url := range urls { | |||||
if i > 2 { | |||||
urlPrefix += "/" + url | |||||
} | |||||
} | |||||
debugUrl := urlPrefix + "?token=" + res.Token | |||||
ctx.Redirect(debugUrl) | |||||
} | |||||
func NotebookDebug2(ctx *context.Context) { | func NotebookDebug2(ctx *context.Context) { | ||||
var err error | |||||
var result *models.GetNotebook2Result | |||||
task := ctx.Cloudbrain | task := ctx.Cloudbrain | ||||
result, err := modelarts.GetNotebook2(task.JobID) | |||||
if task.Type == models.TypeCloudBrainTwo { | |||||
result, err = modelarts.GetNotebook2(task.JobID) | |||||
} else if task.Type == models.TypeCDCenter { | |||||
result, err = modelarts_cd.GetNotebook(task.JobID) | |||||
} | |||||
if err != nil { | if err != nil { | ||||
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil) | ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil) | ||||
return | return | ||||
@@ -437,6 +412,7 @@ func NotebookRestart(ctx *context.Context) { | |||||
var resultCode = "-1" | var resultCode = "-1" | ||||
var errorMsg = "" | var errorMsg = "" | ||||
var status = "" | var status = "" | ||||
var spec *models.Specification | |||||
task := ctx.Cloudbrain | task := ctx.Cloudbrain | ||||
@@ -464,12 +440,40 @@ func NotebookRestart(ctx *context.Context) { | |||||
} | } | ||||
} | } | ||||
oldSpec, err := resource.GetCloudbrainSpec(task.ID) | |||||
if err != nil || oldSpec == nil { | |||||
log.Error("NotebookManage GetCloudbrainSpec error.%v", err) | |||||
errorMsg = "Resource specification not available" | |||||
break | |||||
} | |||||
aiCenterCode := models.AICenterOfCloudBrainTwo | |||||
if task.Type == models.TypeCDCenter { | |||||
aiCenterCode = models.AICenterOfChengdu | |||||
} | |||||
spec, err = resource.GetAndCheckSpec(ctx.User.ID, oldSpec.ID, models.FindSpecsOptions{ | |||||
JobType: models.JobType(task.JobType), | |||||
ComputeResource: models.NPU, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: aiCenterCode}) | |||||
if err != nil || spec == nil { | |||||
log.Error("NotebookManage GetAndCheckSpec error.task.id = %d", task.ID) | |||||
errorMsg = "Resource specification not support any more" | |||||
break | |||||
} | |||||
createTime := timeutil.TimeStampNow() | createTime := timeutil.TimeStampNow() | ||||
param := models.NotebookAction{ | param := models.NotebookAction{ | ||||
Action: models.ActionStart, | Action: models.ActionStart, | ||||
} | } | ||||
res, err := modelarts.ManageNotebook2(task.JobID, param) | |||||
var res *models.NotebookActionResult | |||||
if task.Type == models.TypeCloudBrainTwo { | |||||
res, err = modelarts.ManageNotebook2(task.JobID, param) | |||||
} else if task.Type == models.TypeCDCenter { | |||||
res, err = modelarts_cd.ManageNotebook(task.JobID, param) | |||||
} | |||||
if err != nil { | if err != nil { | ||||
log.Error("ManageNotebook2(%s) failed:%v", task.DisplayJobName, err.Error(), ctx.Data["MsgID"]) | log.Error("ManageNotebook2(%s) failed:%v", task.DisplayJobName, err.Error(), ctx.Data["MsgID"]) | ||||
/* 暂不处理再次调试502的场景,详情见方案 | /* 暂不处理再次调试502的场景,详情见方案 | ||||
@@ -507,8 +511,7 @@ func NotebookRestart(ctx *context.Context) { | |||||
Description: task.Description, | Description: task.Description, | ||||
CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
FlavorCode: task.FlavorCode, | |||||
FlavorName: task.FlavorName, | |||||
Spec: spec, | |||||
} | } | ||||
err = models.RestartCloudbrain(task, newTask) | err = models.RestartCloudbrain(task, newTask) | ||||
@@ -555,7 +558,14 @@ func NotebookStop(ctx *context.Context) { | |||||
Action: models.ActionStop, | Action: models.ActionStop, | ||||
} | } | ||||
res, err := modelarts.ManageNotebook2(task.JobID, param) | |||||
var err error | |||||
var res *models.NotebookActionResult | |||||
if task.Type == models.TypeCloudBrainTwo { | |||||
res, err = modelarts.ManageNotebook2(task.JobID, param) | |||||
} else if task.Type == models.TypeCDCenter { | |||||
res, err = modelarts_cd.ManageNotebook(task.JobID, param) | |||||
} | |||||
if err != nil { | if err != nil { | ||||
log.Error("ManageNotebook2(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | log.Error("ManageNotebook2(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | ||||
resultCode = "-1" | resultCode = "-1" | ||||
@@ -605,7 +615,13 @@ func NotebookDel(ctx *context.Context) { | |||||
return | return | ||||
} | } | ||||
_, err := modelarts.DelNotebook2(task.JobID) | |||||
var err error | |||||
if task.Type == models.TypeCloudBrainTwo { | |||||
_, err = modelarts.DelNotebook2(task.JobID) | |||||
} else if task.Type == models.TypeCDCenter { | |||||
_, err = modelarts_cd.DelNotebook(task.JobID) | |||||
} | |||||
if err != nil { | if err != nil { | ||||
log.Error("DelNotebook2(%s) failed:%v", task.JobName, err.Error()) | log.Error("DelNotebook2(%s) failed:%v", task.JobName, err.Error()) | ||||
if strings.Contains(err.Error(), modelarts.NotebookNotFound) || strings.Contains(err.Error(), modelarts.NotebookNoPermission) || strings.Contains(err.Error(), modelarts.NotebookInvalid) { | if strings.Contains(err.Error(), modelarts.NotebookNotFound) || strings.Contains(err.Error(), modelarts.NotebookNoPermission) || strings.Contains(err.Error(), modelarts.NotebookInvalid) { | ||||
@@ -741,14 +757,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||||
} | } | ||||
ctx.Data["engine_versions"] = versionInfos.Version | 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["params"] = "" | ||||
ctx.Data["branchName"] = ctx.Repo.BranchName | ctx.Data["branchName"] = ctx.Repo.BranchName | ||||
@@ -763,9 +772,33 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | ||||
ctx.Data["WaitCount"] = waitCount | ctx.Data["WaitCount"] = waitCount | ||||
setMultiNodeIfConfigureMatch(ctx) | |||||
return nil | return nil | ||||
} | } | ||||
func prepareCloudbrainTwoTrainSpecs(ctx *context.Context) { | |||||
noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{ | |||||
JobType: models.JobTypeTrain, | |||||
ComputeResource: models.NPU, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: models.AICenterOfCloudBrainTwo, | |||||
}) | |||||
ctx.Data["Specs"] = noteBookSpecs | |||||
} | |||||
func setMultiNodeIfConfigureMatch(ctx *context.Context) { | |||||
modelarts.InitMultiNode() | |||||
if modelarts.MultiNodeConfig != nil { | |||||
for _, info := range modelarts.MultiNodeConfig.Info { | |||||
if isInOrg, _ := models.IsOrganizationMemberByOrgName(info.Org, ctx.User.ID); isInOrg { | |||||
ctx.Data["WorkNode"] = info.Node | |||||
break | |||||
} | |||||
} | |||||
} | |||||
} | |||||
func setSpecBySpecialPoolConfig(ctx *context.Context, jobType string) { | func setSpecBySpecialPoolConfig(ctx *context.Context, jobType string) { | ||||
modelarts.InitSpecialPool() | modelarts.InitSpecialPool() | ||||
@@ -848,13 +881,7 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||||
} | } | ||||
ctx.Data["engine_versions"] = versionInfos.Version | 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) | configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | ||||
if err != nil { | if err != nil { | ||||
@@ -880,6 +907,7 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||||
ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ||||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | ||||
ctx.Data["WaitCount"] = waitCount | ctx.Data["WaitCount"] = waitCount | ||||
setMultiNodeIfConfigureMatch(ctx) | |||||
return nil | return nil | ||||
} | } | ||||
@@ -942,14 +970,12 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||||
} | } | ||||
ctx.Data["engine_versions"] = versionInfos.Version | ctx.Data["engine_versions"] = versionInfos.Version | ||||
var flavorInfos modelarts.Flavor | |||||
if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return err | |||||
prepareCloudbrainTwoTrainSpecs(ctx) | |||||
spec, _ := resource.GetCloudbrainSpec(task.ID) | |||||
if spec != nil { | |||||
log.Info("spec_id = %d", spec.ID) | |||||
ctx.Data["spec_id"] = spec.ID | |||||
} | } | ||||
ctx.Data["flavor_infos"] = flavorInfos.Info | |||||
setSpecBySpecialPoolConfig(ctx, string(models.JobTypeTrain)) | |||||
var Parameters modelarts.Parameters | var Parameters modelarts.Parameters | ||||
if err = json.Unmarshal([]byte(task.Parameters), &Parameters); err != nil { | if err = json.Unmarshal([]byte(task.Parameters), &Parameters); err != nil { | ||||
@@ -1040,13 +1066,7 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai | |||||
} | } | ||||
ctx.Data["engine_versions"] = versionInfos.Version | 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 | var Parameters modelarts.Parameters | ||||
if err = json.Unmarshal([]byte(form.Params), &Parameters); err != nil { | if err = json.Unmarshal([]byte(form.Params), &Parameters); err != nil { | ||||
@@ -1099,7 +1119,6 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
workServerNumber := form.WorkServerNumber | workServerNumber := form.WorkServerNumber | ||||
engineID := form.EngineID | engineID := form.EngineID | ||||
bootFile := strings.TrimSpace(form.BootFile) | bootFile := strings.TrimSpace(form.BootFile) | ||||
flavorCode := form.Flavor | |||||
params := form.Params | params := form.Params | ||||
poolID := form.PoolID | poolID := form.PoolID | ||||
//isSaveParam := form.IsSaveParam | //isSaveParam := form.IsSaveParam | ||||
@@ -1115,6 +1134,13 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
VersionCount := modelarts.VersionCountOne | VersionCount := modelarts.VersionCountOne | ||||
EngineName := form.EngineName | EngineName := form.EngineName | ||||
errStr := checkMultiNode(ctx.User.ID, form.WorkServerNumber) | |||||
if errStr != "" { | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) | count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) | ||||
if err != nil { | if err != nil { | ||||
log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | ||||
@@ -1145,10 +1171,14 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
return | 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) | trainJobErrorNewDataPrepare(ctx, form) | ||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsTrainJobNew, &form) | |||||
ctx.RenderWithErr("Resource specification not available", tplModelArtsTrainJobNew, &form) | |||||
return | return | ||||
} | } | ||||
//Determine whether the task name of the task in the project is duplicated | //Determine whether the task name of the task in the project is duplicated | ||||
@@ -1311,7 +1341,6 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
BootFileUrl: codeObsPath + bootFile, | BootFileUrl: codeObsPath + bootFile, | ||||
BootFile: bootFile, | BootFile: bootFile, | ||||
TrainUrl: outputObsPath, | TrainUrl: outputObsPath, | ||||
FlavorCode: flavorCode, | |||||
WorkServerNumber: workServerNumber, | WorkServerNumber: workServerNumber, | ||||
EngineID: int64(engineID), | EngineID: int64(engineID), | ||||
LogUrl: logObsPath, | LogUrl: logObsPath, | ||||
@@ -1327,6 +1356,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
VersionCount: VersionCount, | VersionCount: VersionCount, | ||||
TotalVersionCount: modelarts.TotalVersionCount, | TotalVersionCount: modelarts.TotalVersionCount, | ||||
DatasetName: datasetNames, | DatasetName: datasetNames, | ||||
Spec: spec, | |||||
} | } | ||||
userCommand, userImageUrl := getUserCommand(engineID, req) | userCommand, userImageUrl := getUserCommand(engineID, req) | ||||
req.UserCommand = userCommand | req.UserCommand = userCommand | ||||
@@ -1349,6 +1379,48 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | ||||
} | } | ||||
func checkMultiNode(userId int64, serverNum int) string { | |||||
if serverNum == 1 { | |||||
return "" | |||||
} | |||||
modelarts.InitMultiNode() | |||||
var isServerNumValid = false | |||||
if modelarts.MultiNodeConfig != nil { | |||||
for _, info := range modelarts.MultiNodeConfig.Info { | |||||
if isInOrg, _ := models.IsOrganizationMemberByOrgName(info.Org, userId); isInOrg { | |||||
if isInNodes(info.Node, serverNum) { | |||||
isServerNumValid = true | |||||
break | |||||
} | |||||
} | |||||
} | |||||
} | |||||
if isServerNumValid { | |||||
return "" | |||||
} else { | |||||
return "repo.modelarts.no_node_right" | |||||
} | |||||
} | |||||
func checkInferenceJobMultiNode(userId int64, serverNum int) string { | |||||
if serverNum == 1 { | |||||
return "" | |||||
} | |||||
return "repo.modelarts.no_node_right" | |||||
} | |||||
func isInNodes(nodes []int, num int) bool { | |||||
for _, node := range nodes { | |||||
if node == num { | |||||
return true | |||||
} | |||||
} | |||||
return false | |||||
} | |||||
func getUserCommand(engineId int, req *modelarts.GenerateTrainJobReq) (string, string) { | func getUserCommand(engineId int, req *modelarts.GenerateTrainJobReq) (string, string) { | ||||
userImageUrl := "" | userImageUrl := "" | ||||
userCommand := "" | userCommand := "" | ||||
@@ -1383,6 +1455,13 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
ctx.Data["PageIsTrainJob"] = true | ctx.Data["PageIsTrainJob"] = true | ||||
var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
errStr := checkMultiNode(ctx.User.ID, form.WorkServerNumber) | |||||
if errStr != "" { | |||||
versionErrorDataPrepare(ctx, form) | |||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsTrainJobVersionNew, &form) | |||||
return | |||||
} | |||||
count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) | count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) | ||||
if err != nil { | if err != nil { | ||||
log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | ||||
@@ -1412,7 +1491,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
workServerNumber := form.WorkServerNumber | workServerNumber := form.WorkServerNumber | ||||
engineID := form.EngineID | engineID := form.EngineID | ||||
bootFile := strings.TrimSpace(form.BootFile) | bootFile := strings.TrimSpace(form.BootFile) | ||||
flavorCode := form.Flavor | |||||
params := form.Params | params := form.Params | ||||
poolID := form.PoolID | poolID := form.PoolID | ||||
//isSaveParam := form.IsSaveParam | //isSaveParam := form.IsSaveParam | ||||
@@ -1450,10 +1528,14 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
return | 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) | versionErrorDataPrepare(ctx, form) | ||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsTrainJobVersionNew, &form) | |||||
ctx.RenderWithErr("Resource specification not available", tplModelArtsTrainJobVersionNew, &form) | |||||
return | return | ||||
} | } | ||||
@@ -1607,7 +1689,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
BootFileUrl: codeObsPath + bootFile, | BootFileUrl: codeObsPath + bootFile, | ||||
BootFile: bootFile, | BootFile: bootFile, | ||||
TrainUrl: outputObsPath, | TrainUrl: outputObsPath, | ||||
FlavorCode: flavorCode, | |||||
WorkServerNumber: workServerNumber, | WorkServerNumber: workServerNumber, | ||||
IsLatestVersion: isLatestVersion, | IsLatestVersion: isLatestVersion, | ||||
EngineID: int64(engineID), | EngineID: int64(engineID), | ||||
@@ -1624,6 +1705,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
PreVersionName: PreVersionName, | PreVersionName: PreVersionName, | ||||
TotalVersionCount: latestTask.TotalVersionCount + 1, | TotalVersionCount: latestTask.TotalVersionCount + 1, | ||||
DatasetName: datasetNames, | DatasetName: datasetNames, | ||||
Spec: spec, | |||||
} | } | ||||
userCommand, userImageUrl := getUserCommand(engineID, req) | userCommand, userImageUrl := getUserCommand(engineID, req) | ||||
req.UserCommand = userCommand | req.UserCommand = userCommand | ||||
@@ -1719,10 +1801,6 @@ func paramCheckCreateTrainJob(form auth.CreateModelArtsTrainJobForm) error { | |||||
return errors.New("启动文件必须是python文件") | return errors.New("启动文件必须是python文件") | ||||
} | } | ||||
if form.WorkServerNumber > 2 || form.WorkServerNumber < 1 { | |||||
log.Error("the WorkServerNumber(%d) must be in (1,2)", form.WorkServerNumber) | |||||
return errors.New("计算节点数必须在1-2之间") | |||||
} | |||||
if form.BranchName == "" { | if form.BranchName == "" { | ||||
log.Error("the branch must not be null!", form.BranchName) | log.Error("the branch must not be null!", form.BranchName) | ||||
return errors.New("代码分支不能为空!") | return errors.New("代码分支不能为空!") | ||||
@@ -1811,7 +1889,6 @@ func TrainJobShow(ctx *context.Context) { | |||||
for i, task := range VersionListTasks { | for i, task := range VersionListTasks { | ||||
var parameters models.Parameters | var parameters models.Parameters | ||||
err := json.Unmarshal([]byte(VersionListTasks[i].Parameters), ¶meters) | err := json.Unmarshal([]byte(VersionListTasks[i].Parameters), ¶meters) | ||||
if err != nil { | if err != nil { | ||||
log.Error("Failed to Unmarshal Parameters: %s (%v)", VersionListTasks[i].Parameters, err) | log.Error("Failed to Unmarshal Parameters: %s (%v)", VersionListTasks[i].Parameters, err) | ||||
@@ -1832,6 +1909,14 @@ func TrainJobShow(ctx *context.Context) { | |||||
datasetList = append(datasetList, GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)) | datasetList = append(datasetList, GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)) | ||||
VersionListTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | VersionListTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | ||||
VersionListTasks[i].CanModify = cloudbrain.CanModifyJob(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) | pager := context.NewPagination(VersionListCount, setting.UI.IssuePagingNum, page, 5) | ||||
@@ -1999,7 +2084,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
workServerNumber := form.WorkServerNumber | workServerNumber := form.WorkServerNumber | ||||
engineID := form.EngineID | engineID := form.EngineID | ||||
bootFile := strings.TrimSpace(form.BootFile) | bootFile := strings.TrimSpace(form.BootFile) | ||||
flavorCode := form.Flavor | |||||
params := form.Params | params := form.Params | ||||
poolID := form.PoolID | poolID := form.PoolID | ||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
@@ -2021,6 +2105,13 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
ckptUrl := "/" + form.TrainUrl + form.CkptName | ckptUrl := "/" + form.TrainUrl + form.CkptName | ||||
log.Info("ckpt url:" + ckptUrl) | log.Info("ckpt url:" + ckptUrl) | ||||
errStr := checkInferenceJobMultiNode(ctx.User.ID, form.WorkServerNumber) | |||||
if errStr != "" { | |||||
inferenceJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsInferenceJobNew, &form) | |||||
return | |||||
} | |||||
count, err := models.GetCloudbrainInferenceJobCountByUserID(ctx.User.ID) | count, err := models.GetCloudbrainInferenceJobCountByUserID(ctx.User.ID) | ||||
if err != nil { | if err != nil { | ||||
log.Error("GetCloudbrainInferenceJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainInferenceJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | ||||
@@ -2069,13 +2160,16 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
} | } | ||||
} | } | ||||
errStr := checkModelArtsSpecialPool(ctx, flavorCode, string(models.JobTypeInference)) | |||||
if errStr != "" { | |||||
spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{ | |||||
JobType: models.JobTypeInference, | |||||
ComputeResource: models.NPU, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: models.AICenterOfCloudBrainTwo}) | |||||
if err != nil || spec == nil { | |||||
inferenceJobErrorNewDataPrepare(ctx, form) | inferenceJobErrorNewDataPrepare(ctx, form) | ||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsInferenceJobNew, &form) | |||||
ctx.RenderWithErr("Resource specification not available", tplModelArtsInferenceJobNew, &form) | |||||
return | return | ||||
} | } | ||||
//todo: del the codeLocalPath | //todo: del the codeLocalPath | ||||
_, err = ioutil.ReadDir(codeLocalPath) | _, err = ioutil.ReadDir(codeLocalPath) | ||||
if err == nil { | if err == nil { | ||||
@@ -2127,7 +2221,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
datasUrlList, dataUrl, datasetNames, isMultiDataset, err := getDatasUrlListByUUIDS(uuid) | datasUrlList, dataUrl, datasetNames, isMultiDataset, err := getDatasUrlListByUUIDS(uuid) | ||||
if err != nil { | if err != nil { | ||||
inferenceJobErrorNewDataPrepare(ctx, form) | inferenceJobErrorNewDataPrepare(ctx, form) | ||||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsInferenceJobNew, &form) | |||||
ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form) | |||||
return | return | ||||
} | } | ||||
dataPath := dataUrl | dataPath := dataUrl | ||||
@@ -2183,7 +2277,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
BootFileUrl: codeObsPath + bootFile, | BootFileUrl: codeObsPath + bootFile, | ||||
BootFile: bootFile, | BootFile: bootFile, | ||||
TrainUrl: trainUrl, | TrainUrl: trainUrl, | ||||
FlavorCode: flavorCode, | |||||
WorkServerNumber: workServerNumber, | WorkServerNumber: workServerNumber, | ||||
EngineID: int64(engineID), | EngineID: int64(engineID), | ||||
LogUrl: logObsPath, | LogUrl: logObsPath, | ||||
@@ -2203,6 +2296,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
ModelVersion: modelVersion, | ModelVersion: modelVersion, | ||||
CkptName: ckptName, | CkptName: ckptName, | ||||
ResultUrl: resultObsPath, | ResultUrl: resultObsPath, | ||||
Spec: spec, | |||||
DatasetName: datasetNames, | DatasetName: datasetNames, | ||||
} | } | ||||
@@ -2245,7 +2339,7 @@ func checkModelArtsSpecialPool(ctx *context.Context, flavorCode string, jobType | |||||
if !isMatchPool { | if !isMatchPool { | ||||
isMatchSpec := false | isMatchSpec := false | ||||
if jobType == string(models.JobTypeDebug) { | if jobType == string(models.JobTypeDebug) { | ||||
for _, flavor := range modelarts.FlavorInfos.FlavorInfo { | |||||
for _, flavor := range setting.StFlavorInfo.FlavorInfo { | |||||
if flavor.Value == flavorCode { | if flavor.Value == flavorCode { | ||||
isMatchSpec = true | isMatchSpec = true | ||||
break | break | ||||
@@ -2383,14 +2477,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
} | } | ||||
ctx.Data["engine_versions"] = versionInfos.Version | 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["params"] = "" | ||||
ctx.Data["branchName"] = ctx.Repo.BranchName | ctx.Data["branchName"] = ctx.Repo.BranchName | ||||
@@ -2421,6 +2508,16 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
return nil | 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 { | func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArtsInferenceJobForm) error { | ||||
ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
@@ -2455,14 +2552,7 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel | |||||
return err | return err | ||||
} | } | ||||
ctx.Data["engine_versions"] = versionInfos.Version | ctx.Data["engine_versions"] = versionInfos.Version | ||||
var flavorInfos modelarts.Flavor | |||||
if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return err | |||||
} | |||||
ctx.Data["flavor_infos"] = flavorInfos.Info | |||||
setSpecBySpecialPoolConfig(ctx, string(models.JobTypeInference)) | |||||
prepareCloudbrainTwoInferenceSpecs(ctx) | |||||
configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | ||||
if err != nil { | if err != nil { | ||||
@@ -2537,7 +2627,7 @@ func InferenceJobShow(ctx *context.Context) { | |||||
} else { | } else { | ||||
task.Parameters = "" | task.Parameters = "" | ||||
} | } | ||||
prepareSpec4Show(ctx, task) | |||||
LabelName := strings.Fields(task.LabelName) | LabelName := strings.Fields(task.LabelName) | ||||
ctx.Data["labelName"] = LabelName | ctx.Data["labelName"] = LabelName | ||||
ctx.Data["jobID"] = jobID | ctx.Data["jobID"] = jobID | ||||
@@ -2,3 +2,4 @@ package response | |||||
var RESOURCE_QUEUE_NOT_AVAILABLE = &BizError{Code: 1001, Err: "resource queue not available"} | 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_EXIST = &BizError{Code: 1002, Err: "specification not exist"} | ||||
var SPECIFICATION_NOT_AVAILABLE = &BizError{Code: 1003, Err: "specification not available"} |
@@ -836,14 +836,12 @@ func Cloudbrains(ctx *context.Context) { | |||||
ctx.ServerError("Get job failed:", err) | ctx.ServerError("Get job failed:", err) | ||||
return | return | ||||
} | } | ||||
models.LoadSpecs4CloudbrainInfo(ciTasks) | |||||
for i, task := range ciTasks { | for i, task := range ciTasks { | ||||
ciTasks[i].CanDebug = true | ciTasks[i].CanDebug = true | ||||
ciTasks[i].CanDel = true | ciTasks[i].CanDel = true | ||||
ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | ||||
ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) | ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) | ||||
_, cardType, _ := repo.GetCloudbrainCardNumAndType(task.Cloudbrain) | |||||
ciTasks[i].Cloudbrain.CardType = cardType | |||||
ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) | ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) | ||||
} | } | ||||
@@ -2,12 +2,19 @@ package resource | |||||
import ( | import ( | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
"code.gitea.io/gitea/modules/cloudbrain" | |||||
"code.gitea.io/gitea/modules/grampus" | "code.gitea.io/gitea/modules/grampus" | ||||
"code.gitea.io/gitea/modules/log" | "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/routers/response" | ||||
"code.gitea.io/gitea/services/admin/operate_log" | "code.gitea.io/gitea/services/admin/operate_log" | ||||
"encoding/json" | |||||
"errors" | |||||
"fmt" | "fmt" | ||||
"strconv" | |||||
"strings" | "strings" | ||||
"time" | |||||
) | ) | ||||
func AddResourceSpecification(doerId int64, req models.ResourceSpecificationReq) error { | func AddResourceSpecification(doerId int64, req models.ResourceSpecificationReq) error { | ||||
@@ -92,6 +99,7 @@ func SyncGrampusSpecs(doerId int64) error { | |||||
GPUMemGiB: gpuMemGiB, | GPUMemGiB: gpuMemGiB, | ||||
Status: models.SpecNotVerified, | Status: models.SpecNotVerified, | ||||
IsAutomaticSync: true, | IsAutomaticSync: true, | ||||
IsAvailable: true, | |||||
CreatedBy: doerId, | CreatedBy: doerId, | ||||
UpdatedBy: doerId, | UpdatedBy: doerId, | ||||
}) | }) | ||||
@@ -103,6 +111,7 @@ func SyncGrampusSpecs(doerId int64) error { | |||||
CpuCores: spec.SpecInfo.CpuCoreNum, | CpuCores: spec.SpecInfo.CpuCoreNum, | ||||
MemGiB: memGiB, | MemGiB: memGiB, | ||||
GPUMemGiB: gpuMemGiB, | GPUMemGiB: gpuMemGiB, | ||||
IsAvailable: true, | |||||
UpdatedBy: doerId, | 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 { | if q, err := models.GetResourceQueue(&models.ResourceQueue{ID: spec.QueueId}); err != nil || q == nil { | ||||
return response.RESOURCE_QUEUE_NOT_AVAILABLE | return response.RESOURCE_QUEUE_NOT_AVAILABLE | ||||
} | } | ||||
if !spec.IsAvailable { | |||||
return response.SPECIFICATION_NOT_AVAILABLE | |||||
} | |||||
err = models.ResourceSpecOnShelf(id, unitPrice) | err = models.ResourceSpecOnShelf(id, unitPrice) | ||||
if err != nil { | if err != nil { | ||||
return response.NewBizError(err) | return response.NewBizError(err) | ||||
@@ -184,3 +195,461 @@ func AddSpecOperateLog(doerId int64, operateType string, newValue, oldValue *mod | |||||
Comment: comment, | Comment: comment, | ||||
}) | }) | ||||
} | } | ||||
func FindAvailableSpecs(userId int64, opts models.FindSpecsOptions) ([]*models.Specification, error) { | |||||
r, err := models.FindSpecs(opts) | |||||
if err != nil { | |||||
log.Error("FindAvailableSpecs error.%v", err) | |||||
return nil, err | |||||
} | |||||
//filter exclusive specs | |||||
specs := filterExclusiveSpecs(r, userId) | |||||
//distinct by sourceSpecId | |||||
specs = distinctSpecs(specs) | |||||
return specs, err | |||||
} | |||||
func filterExclusiveSpecs(r []*models.Specification, userId int64) []*models.Specification { | |||||
specs := make([]*models.Specification, 0, len(r)) | |||||
specMap := make(map[int64]string, 0) | |||||
for i := 0; i < len(r); i++ { | |||||
spec := r[i] | |||||
if _, has := specMap[spec.ID]; has { | |||||
continue | |||||
} | |||||
if !spec.IsExclusive { | |||||
specs = append(specs, spec) | |||||
specMap[spec.ID] = "" | |||||
continue | |||||
} | |||||
orgs := strings.Split(spec.ExclusiveOrg, ";") | |||||
for _, org := range orgs { | |||||
isMember, _ := models.IsOrganizationMemberByOrgName(org, userId) | |||||
if isMember { | |||||
specs = append(specs, spec) | |||||
specMap[spec.ID] = "" | |||||
break | |||||
} | |||||
} | |||||
} | |||||
return specs | |||||
} | |||||
func distinctSpecs(r []*models.Specification) []*models.Specification { | |||||
specs := make([]*models.Specification, 0, len(r)) | |||||
sourceSpecIdMap := make(map[string]string, 0) | |||||
for i := 0; i < len(r); i++ { | |||||
spec := r[i] | |||||
if spec.SourceSpecId == "" { | |||||
specs = append(specs, spec) | |||||
continue | |||||
} | |||||
if _, has := sourceSpecIdMap[spec.SourceSpecId]; has { | |||||
continue | |||||
} | |||||
specs = append(specs, spec) | |||||
sourceSpecIdMap[spec.SourceSpecId] = "" | |||||
} | |||||
return specs | |||||
} | |||||
func GetAndCheckSpec(userId int64, specId int64, opts models.FindSpecsOptions) (*models.Specification, error) { | |||||
if specId == 0 { | |||||
return nil, nil | |||||
} | |||||
opts.SpecId = specId | |||||
r, err := FindAvailableSpecs(userId, opts) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
if r == nil || len(r) == 0 { | |||||
return nil, nil | |||||
} | |||||
return r[0], nil | |||||
} | |||||
func InsertCloudbrainSpec(cloudbrainId int64, s *models.Specification) error { | |||||
c := models.CloudbrainSpec{ | |||||
CloudbrainID: cloudbrainId, | |||||
SpecId: s.ID, | |||||
SourceSpecId: s.SourceSpecId, | |||||
AccCardsNum: s.AccCardsNum, | |||||
AccCardType: s.AccCardType, | |||||
CpuCores: s.CpuCores, | |||||
MemGiB: s.MemGiB, | |||||
GPUMemGiB: s.GPUMemGiB, | |||||
ShareMemGiB: s.ShareMemGiB, | |||||
ComputeResource: s.ComputeResource, | |||||
UnitPrice: s.UnitPrice, | |||||
QueueId: s.QueueId, | |||||
QueueCode: s.QueueCode, | |||||
Cluster: s.Cluster, | |||||
AiCenterCode: s.AiCenterCode, | |||||
AiCenterName: s.AiCenterName, | |||||
IsExclusive: s.IsExclusive, | |||||
ExclusiveOrg: s.ExclusiveOrg, | |||||
} | |||||
_, err := models.InsertCloudbrainSpec(c) | |||||
if err != nil { | |||||
log.Error("InsertCloudbrainSpec error.CloudbrainSpec=%v. err=%v", c, err) | |||||
return err | |||||
} | |||||
return nil | |||||
} | |||||
func GetCloudbrainSpec(cloudbrainId int64) (*models.Specification, error) { | |||||
c, err := models.GetCloudbrainSpecByID(cloudbrainId) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
if c == nil { | |||||
return nil, nil | |||||
} | |||||
return c.ConvertToSpecification(), nil | |||||
} | |||||
func RefreshHistorySpec(scopeAll bool, ids []int64) (int64, int64, error) { | |||||
var success int64 | |||||
var total int64 | |||||
if !scopeAll { | |||||
if ids == nil || len(ids) == 0 { | |||||
return 0, 0, nil | |||||
} | |||||
total = int64(len(ids)) | |||||
tasks, err := models.GetCloudbrainWithDeletedByIDs(ids) | |||||
if err != nil { | |||||
return total, 0, err | |||||
} | |||||
for _, task := range tasks { | |||||
err = RefreshOneHistorySpec(task) | |||||
if err != nil { | |||||
log.Error("RefreshOneHistorySpec error.%v", err) | |||||
continue | |||||
} | |||||
success++ | |||||
} | |||||
} else { | |||||
page := 1 | |||||
pageSize := 100 | |||||
n, err := models.CountNoSpecHistoricTask() | |||||
if err != nil { | |||||
log.Error("FindNoSpecHistoricTask CountNoSpecHistoricTask error. e=%v", err) | |||||
return 0, 0, err | |||||
} | |||||
total = n | |||||
for i := 0; i < 500; i++ { | |||||
list, err := models.FindCloudbrainTask(page, pageSize) | |||||
page++ | |||||
if err != nil { | |||||
log.Error("FindCloudbrainTask error.page=%d pageSize=%d e=%v", page, pageSize, err) | |||||
return total, success, err | |||||
} | |||||
if len(list) == 0 { | |||||
log.Info("RefreshHistorySpec. list is empty") | |||||
break | |||||
} | |||||
for _, task := range list { | |||||
s, err := GetCloudbrainSpec(task.ID) | |||||
if err != nil { | |||||
log.Error("RefreshHistorySpec GetCloudbrainSpec error.%v", err) | |||||
continue | |||||
} | |||||
if s != nil { | |||||
continue | |||||
} | |||||
err = RefreshOneHistorySpec(task) | |||||
if err != nil { | |||||
log.Error("RefreshOneHistorySpec error.%v", err) | |||||
continue | |||||
} | |||||
success++ | |||||
} | |||||
if len(list) < pageSize { | |||||
log.Info("RefreshHistorySpec. list < pageSize") | |||||
break | |||||
} | |||||
} | |||||
} | |||||
return total, success, nil | |||||
} | |||||
func RefreshOneHistorySpec(task *models.Cloudbrain) error { | |||||
var spec *models.Specification | |||||
var err error | |||||
switch task.Type { | |||||
case models.TypeCloudBrainOne: | |||||
spec, err = getCloudbrainOneSpec(task) | |||||
case models.TypeCloudBrainTwo: | |||||
spec, err = getCloudbrainTwoSpec(task) | |||||
case models.TypeC2Net: | |||||
spec, err = getGrampusSpec(task) | |||||
} | |||||
if err != nil { | |||||
log.Error("find spec error,task.ID=%d err=%v", task.ID, err) | |||||
return err | |||||
} | |||||
if spec == nil { | |||||
log.Error("find spec failed,task.ID=%d", task.ID) | |||||
return errors.New("find spec failed") | |||||
} | |||||
return InsertCloudbrainSpec(task.ID, spec) | |||||
} | |||||
func getCloudbrainOneSpec(task *models.Cloudbrain) (*models.Specification, error) { | |||||
if task.GpuQueue == "" { | |||||
log.Info("gpu queue is empty.task.ID = %d", task.ID) | |||||
return nil, nil | |||||
} | |||||
//find from config | |||||
spec, err := findCloudbrainOneSpecFromConfig(task) | |||||
if err != nil { | |||||
log.Error("getCloudbrainOneSpec findCloudbrainOneSpecFromConfig error.%v", err) | |||||
return nil, err | |||||
} | |||||
if spec != nil { | |||||
return spec, nil | |||||
} | |||||
//find from remote | |||||
return findCloudbrainOneSpecFromRemote(task) | |||||
} | |||||
func findCloudbrainOneSpecFromRemote(task *models.Cloudbrain) (*models.Specification, error) { | |||||
time.Sleep(200 * time.Millisecond) | |||||
log.Info("start findCloudbrainOneSpecFromRemote") | |||||
result, err := cloudbrain.GetJob(task.JobID) | |||||
if err != nil { | |||||
log.Error("getCloudbrainOneSpec error. %v", err) | |||||
return nil, err | |||||
} | |||||
if result == nil { | |||||
log.Info("findCloudbrainOneSpecFromRemote failed,result is empty.task.ID=%d", task.ID) | |||||
return nil, nil | |||||
} | |||||
jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | |||||
memSize, _ := models.ParseMemSizeFromGrampus(jobRes.Resource.Memory) | |||||
if task.ComputeResource == "CPU/GPU" { | |||||
task.ComputeResource = models.GPU | |||||
} | |||||
var shmMB float32 | |||||
if jobRes.Config.TaskRoles != nil && len(jobRes.Config.TaskRoles) > 0 { | |||||
shmMB = float32(jobRes.Config.TaskRoles[0].ShmMB) / 1024 | |||||
if jobRes.Config.TaskRoles[0].ShmMB == 103600 { | |||||
shmMB = 100 | |||||
} else if jobRes.Config.TaskRoles[0].ShmMB == 51800 { | |||||
shmMB = 50 | |||||
} | |||||
} | |||||
opt := models.FindSpecsOptions{ | |||||
ComputeResource: task.ComputeResource, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: models.AICenterOfCloudBrainOne, | |||||
QueueCode: task.GpuQueue, | |||||
AccCardsNum: jobRes.Resource.NvidiaComGpu, | |||||
UseAccCardsNum: true, | |||||
CpuCores: jobRes.Resource.CPU, | |||||
UseCpuCores: true, | |||||
MemGiB: memSize, | |||||
UseMemGiB: memSize > 0, | |||||
ShareMemGiB: shmMB, | |||||
UseShareMemGiB: shmMB > 0, | |||||
RequestAll: true, | |||||
} | |||||
specs, err := models.FindSpecs(opt) | |||||
if err != nil { | |||||
log.Error("getCloudbrainOneSpec from remote error,%v", err) | |||||
return nil, err | |||||
} | |||||
if len(specs) == 1 { | |||||
return specs[0], nil | |||||
} | |||||
if len(specs) == 0 { | |||||
s, err := InitQueueAndSpec(opt, "云脑一", "处理历史云脑任务时自动添加") | |||||
if err != nil { | |||||
log.Error("getCloudbrainOneSpec InitQueueAndSpec error.err=%v", err) | |||||
return nil, nil | |||||
} | |||||
return s, nil | |||||
} | |||||
log.Error("Too many results matched.size=%d opt=%+v", len(specs), opt) | |||||
return nil, nil | |||||
} | |||||
func findCloudbrainOneSpecFromConfig(task *models.Cloudbrain) (*models.Specification, error) { | |||||
//find from config | |||||
var specConfig *models.ResourceSpec | |||||
hasSpec := false | |||||
if task.JobType == string(models.JobTypeTrain) { | |||||
if cloudbrain.TrainResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||||
} | |||||
for _, tmp := range cloudbrain.TrainResourceSpecs.ResourceSpec { | |||||
if tmp.Id == task.ResourceSpecId { | |||||
hasSpec = true | |||||
specConfig = tmp | |||||
break | |||||
} | |||||
} | |||||
} else if task.JobType == string(models.JobTypeInference) { | |||||
if cloudbrain.InferenceResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.InferenceResourceSpecs), &cloudbrain.InferenceResourceSpecs) | |||||
} | |||||
for _, tmp := range cloudbrain.InferenceResourceSpecs.ResourceSpec { | |||||
if tmp.Id == task.ResourceSpecId { | |||||
hasSpec = true | |||||
specConfig = tmp | |||||
break | |||||
} | |||||
} | |||||
} else { | |||||
if cloudbrain.ResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||||
} | |||||
for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { | |||||
if tmp.Id == task.ResourceSpecId { | |||||
hasSpec = true | |||||
specConfig = tmp | |||||
break | |||||
} | |||||
} | |||||
} | |||||
if !hasSpec && cloudbrain.SpecialPools != nil { | |||||
for _, specialPool := range cloudbrain.SpecialPools.Pools { | |||||
if specialPool.ResourceSpec != nil { | |||||
for _, spec := range specialPool.ResourceSpec { | |||||
if task.ResourceSpecId == spec.Id { | |||||
hasSpec = true | |||||
specConfig = spec | |||||
break | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
if specConfig == nil { | |||||
log.Error("getCloudbrainOneSpec from config failed,task.ResourceSpecId=%d", task.ResourceSpecId) | |||||
return nil, nil | |||||
} | |||||
if task.ComputeResource == "CPU/GPU" { | |||||
task.ComputeResource = models.GPU | |||||
} | |||||
shareMemMiB := float32(specConfig.ShareMemMiB) / 1024 | |||||
if specConfig.ShareMemMiB == 103600 { | |||||
shareMemMiB = 100 | |||||
} else if specConfig.ShareMemMiB == 51800 { | |||||
shareMemMiB = 50 | |||||
} | |||||
opt := models.FindSpecsOptions{ | |||||
JobType: models.JobType(task.JobType), | |||||
ComputeResource: task.ComputeResource, | |||||
Cluster: models.OpenICluster, | |||||
AiCenterCode: models.AICenterOfCloudBrainOne, | |||||
QueueCode: task.GpuQueue, | |||||
AccCardsNum: specConfig.GpuNum, | |||||
UseAccCardsNum: true, | |||||
CpuCores: specConfig.CpuNum, | |||||
UseCpuCores: true, | |||||
MemGiB: float32(specConfig.MemMiB) / 1024, | |||||
UseMemGiB: true, | |||||
ShareMemGiB: shareMemMiB, | |||||
UseShareMemGiB: true, | |||||
RequestAll: true, | |||||
} | |||||
specs, err := models.FindSpecs(opt) | |||||
if err != nil { | |||||
log.Error("getCloudbrainOneSpec from config error,%v", err) | |||||
return nil, err | |||||
} | |||||
if len(specs) > 1 { | |||||
log.Error("Too many results matched.size=%d opt=%+v", len(specs), opt) | |||||
return nil, nil | |||||
} | |||||
if len(specs) == 0 { | |||||
s, err := InitQueueAndSpec(opt, "云脑一", "处理历史云脑任务时自动添加") | |||||
if err != nil { | |||||
log.Error("getCloudbrainOneSpec InitQueueAndSpec error.err=%v", err) | |||||
return nil, nil | |||||
} | |||||
return s, nil | |||||
} | |||||
return specs[0], nil | |||||
} | |||||
func getCloudbrainTwoSpec(task *models.Cloudbrain) (*models.Specification, error) { | |||||
specMap, err := models.GetCloudbrainTwoSpecs() | |||||
if err != nil { | |||||
log.Error("InitCloudbrainTwoSpecs err.%v", err) | |||||
return nil, err | |||||
} | |||||
if task.FlavorCode != "" { | |||||
return specMap[task.FlavorCode], nil | |||||
} | |||||
time.Sleep(200 * time.Millisecond) | |||||
log.Info("start getCloudbrainTwoSpec FromRemote") | |||||
if task.JobType == string(models.JobTypeDebug) { | |||||
result, err := modelarts.GetNotebook2(task.JobID) | |||||
if err != nil { | |||||
log.Error("getCloudbrainTwoSpec GetNotebook2 error.%v", err) | |||||
return nil, err | |||||
} | |||||
if result != nil { | |||||
return specMap[result.Flavor], nil | |||||
} | |||||
} else if task.JobType == string(models.JobTypeTrain) || task.JobType == string(models.JobTypeInference) { | |||||
result, err := modelarts.GetTrainJob(task.JobID, strconv.FormatInt(task.VersionID, 10)) | |||||
if err != nil { | |||||
log.Error("getCloudbrainTwoSpec GetTrainJob error:%v", task.JobName, err) | |||||
return nil, err | |||||
} | |||||
if result != nil { | |||||
return specMap[result.Flavor.Code], nil | |||||
} | |||||
} | |||||
return nil, nil | |||||
} | |||||
func getGrampusSpec(task *models.Cloudbrain) (*models.Specification, error) { | |||||
specMap, err := models.GetGrampusSpecs() | |||||
if err != nil { | |||||
log.Error("GetGrampusSpecs err.%v", err) | |||||
return nil, err | |||||
} | |||||
if task.AiCenter != "" { | |||||
c := strings.Split(task.AiCenter, "+") | |||||
spec := specMap[task.FlavorCode+"_"+c[0]] | |||||
if spec != nil { | |||||
return spec, nil | |||||
} | |||||
} | |||||
return specMap[task.FlavorCode], nil | |||||
} | |||||
func InitQueueAndSpec(opt models.FindSpecsOptions, aiCenterName string, remark string) (*models.Specification, error) { | |||||
return models.InitQueueAndSpec(models.ResourceQueue{ | |||||
QueueCode: opt.QueueCode, | |||||
Cluster: opt.Cluster, | |||||
AiCenterCode: opt.AiCenterCode, | |||||
AiCenterName: aiCenterName, | |||||
ComputeResource: opt.ComputeResource, | |||||
AccCardType: models.GetCloudbrainOneAccCardType(opt.QueueCode), | |||||
Remark: remark, | |||||
}, models.ResourceSpecification{ | |||||
AccCardsNum: opt.AccCardsNum, | |||||
CpuCores: opt.CpuCores, | |||||
MemGiB: opt.MemGiB, | |||||
GPUMemGiB: opt.GPUMemGiB, | |||||
ShareMemGiB: opt.ShareMemGiB, | |||||
Status: models.SpecOffShelf, | |||||
IsAvailable: true, | |||||
}) | |||||
} |
@@ -1,4 +1,5 @@ | |||||
{{template "base/head" .}} | {{template "base/head" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<!-- 弹窗 --> | <!-- 弹窗 --> | ||||
<div id="mask"> | <div id="mask"> | ||||
<div id="loadingPage"> | <div id="loadingPage"> | ||||
@@ -175,10 +176,17 @@ | |||||
</div> | </div> | ||||
<!-- XPU类型 --> | <!-- XPU类型 --> | ||||
<div class="one wide column text center nowrap" style="width:8% !important;"> | <div class="one wide column text center nowrap" style="width:8% !important;"> | ||||
<span style="font-size: 12px;" title="{{.CardType}}"> | |||||
{{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||||
</span> | |||||
</div> | |||||
<span style="font-size: 12px;" title="" class="card_type_{{.DisplayJobName}}_{{$JobID}}"></span> | |||||
</div> | |||||
<script> | |||||
(function(){ | |||||
var spec = {{.Spec}} || {}; | |||||
var cardType = getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType) || '--'; | |||||
var spanEl = document.querySelector('.card_type_{{.DisplayJobName}}_{{$JobID}}'); | |||||
spanEl.setAttribute('title', cardType); | |||||
spanEl.innerText = cardType; | |||||
})(); | |||||
</script> | |||||
<!-- 创建者 --> | <!-- 创建者 --> | ||||
<div class="one wide column text center nowrap" style="width:4% !important;"> | <div class="one wide column text center nowrap" style="width:4% !important;"> | ||||
{{if .User.Name}} | {{if .User.Name}} | ||||
@@ -4,7 +4,7 @@ | |||||
{{template "admin/navbar" .}} | {{template "admin/navbar" .}} | ||||
<div class="ui container"> | <div class="ui container"> | ||||
<div id="__vue-root"></div> | <div id="__vue-root"></div> | ||||
</duv> | |||||
</div> | |||||
</div> | </div> | ||||
<script src="{{StaticUrlPrefix}}/js/vp-resources-queue.js?v={{MD5 AppVer}}"></script> | <script src="{{StaticUrlPrefix}}/js/vp-resources-queue.js?v={{MD5 AppVer}}"></script> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} |
@@ -4,7 +4,7 @@ | |||||
{{template "admin/navbar" .}} | {{template "admin/navbar" .}} | ||||
<div class="ui container"> | <div class="ui container"> | ||||
<div id="__vue-root"></div> | <div id="__vue-root"></div> | ||||
</duv> | |||||
</div> | |||||
</div> | </div> | ||||
<script src="{{StaticUrlPrefix}}/js/vp-resources-scene.js?v={{MD5 AppVer}}"></script> | <script src="{{StaticUrlPrefix}}/js/vp-resources-scene.js?v={{MD5 AppVer}}"></script> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} |
@@ -4,7 +4,7 @@ | |||||
{{template "admin/navbar" .}} | {{template "admin/navbar" .}} | ||||
<div class="ui container"> | <div class="ui container"> | ||||
<div id="__vue-root"></div> | <div id="__vue-root"></div> | ||||
</duv> | |||||
</div> | |||||
</div> | </div> | ||||
<script src="{{StaticUrlPrefix}}/js/vp-resources-specification.js?v={{MD5 AppVer}}"></script> | <script src="{{StaticUrlPrefix}}/js/vp-resources-specification.js?v={{MD5 AppVer}}"></script> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} |
@@ -0,0 +1,25 @@ | |||||
<div style="display:inline-block;"> | |||||
<div style="display:flex;align-items:center;color:#f2711c;"> | |||||
<i class="ri-error-warning-line" style="margin-right: 0.5rem; font-size: 14px"></i> | |||||
<span style="font-size: 12px">{{.i18n.Tr "repo.wait_count_start"}} <span class="__task_wait_count__">{{.WaitCount}}</span> {{.i18n.Tr "repo.wait_count_end"}}</span> | |||||
</div> | |||||
</div> | |||||
<script> | |||||
;(function() { | |||||
var queuesDetail = {{.QueuesDetail}}; | |||||
if (queuesDetail) { | |||||
function changeSpecs() { | |||||
var specsSelEl = $('select#__specs__'); | |||||
var seldOption = specsSelEl.find('option:selected'); | |||||
var queueCode = seldOption.attr('queueCode'); | |||||
$('span.__task_wait_count__').text(queuesDetail[queueCode] || 0); | |||||
}; | |||||
$('body').on('change', 'select#__specs__', function(e) { | |||||
changeSpecs(); | |||||
}); | |||||
setTimeout(function() { | |||||
changeSpecs(); | |||||
}, 50); | |||||
} | |||||
})(); | |||||
</script> |
@@ -51,9 +51,12 @@ | |||||
<a class="active item model_benchmark" | <a class="active item model_benchmark" | ||||
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | ||||
</div> | </div> | ||||
{{template "custom/wait_count_train" Dict "ctx" $ "type" .benchmark_gpu_types}} | |||||
</div> | </div> | ||||
<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"> | <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> | <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" | <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> | onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | ||||
</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.gpu_type"}}</label> | <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类型" | <select id="cloudbrain_gpu_type" class="ui search dropdown width48" placeholder="选择GPU类型" | ||||
name="gpu_type"> | name="gpu_type"> | ||||
@@ -79,7 +82,7 @@ | |||||
<option value="{{.Queue}}">{{.Value}}</option> | <option value="{{.Queue}}">{{.Value}}</option> | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div> | |||||
</div>--> | |||||
<div class="required unite min_title two inline fields" style="margin-left: 80px;"> | <div class="required unite min_title two inline fields" style="margin-left: 80px;"> | ||||
<div class="required ten wide field" style="width: 26.5% !important;"> | <div class="required ten wide field" style="width: 26.5% !important;"> | ||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label> | ||||
@@ -112,7 +115,7 @@ | |||||
<div id="images-new-cb"> | <div id="images-new-cb"> | ||||
</div> | </div> | ||||
{{template "custom/select_dataset_train" .}} | {{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> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | ||||
<select id="cloudbrain_resource_spec" class="ui search dropdown" | <select id="cloudbrain_resource_spec" class="ui search dropdown" | ||||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | ||||
@@ -123,6 +126,13 @@ | |||||
</option> | </option> | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required min_title inline field" style="margin-top:2rem;"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
<select id="__specs__" class="ui search dropdown width48" | |||||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||||
name="spec_id"> | |||||
</select> | |||||
</div> | </div> | ||||
<div class="inline min_title field"> | <div class="inline min_title field"> | ||||
<label class="label-fix-width" style="font-weight: normal;"></label> | <label class="label-fix-width" style="font-weight: normal;"></label> | ||||
@@ -146,10 +156,13 @@ | |||||
<a class="item model_benchmark" | <a class="item model_benchmark" | ||||
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | ||||
</div> | </div> | ||||
{{template "custom/wait_count_train" Dict "ctx" $ "type" .benchmark_gpu_types}} | |||||
</div> | </div> | ||||
<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"> | <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> | <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" | <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> | onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | ||||
</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.gpu_type"}}</label> | <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类型" | <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" | ||||
style='width:385px' name="gpu_type"> | style='width:385px' name="gpu_type"> | ||||
@@ -175,7 +188,7 @@ | |||||
<option value="{{.Queue}}">{{.Value}}</option> | <option value="{{.Queue}}">{{.Value}}</option> | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div> | |||||
</div>--> | |||||
<div class="required unite inline min_title fields" style="width: 90%;margin-left: 5.7rem;"> | <div class="required unite inline min_title fields" style="width: 90%;margin-left: 5.7rem;"> | ||||
<div class="required eight wide field"> | <div class="required eight wide field"> | ||||
<label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label> | <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 id="images-new-cb"> | ||||
</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> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | ||||
<select id="cloudbrain_resource_spec" class="ui search dropdown" | <select id="cloudbrain_resource_spec" class="ui search dropdown" | ||||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | ||||
@@ -212,6 +225,14 @@ | |||||
</option> | </option> | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required min_title inline field"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
<select id="__specs__" class="ui search dropdown width48" | |||||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||||
name="spec_id"> | |||||
</select> | |||||
</div> | </div> | ||||
<div class="inline min_title field required"> | <div class="inline min_title field required"> | ||||
@@ -245,7 +266,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
let createFlag = false | let createFlag = false | ||||
@@ -304,6 +325,7 @@ | |||||
} | } | ||||
} | } | ||||
} | } | ||||
var isValidate = false; | |||||
function validate() { | function validate() { | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -327,12 +349,18 @@ | |||||
} | } | ||||
] | ] | ||||
}, | }, | ||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | |||||
}, | }, | ||||
onSuccess: function () { | onSuccess: function () { | ||||
// $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function (e) { | onFailure: function (e) { | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -342,4 +370,16 @@ | |||||
$('.ui.create_train_job.green.button').click(function (e) { | $('.ui.create_train_job.green.button').click(function (e) { | ||||
validate() | 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> | </script> |
@@ -256,8 +256,9 @@ | |||||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | ||||
<a class="active item" | <a class="active item" | ||||
data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | ||||
<a class="item" data-tab="second{{$k}}" | |||||
onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||||
<a class="item log_bottom" data-tab="second{{$k}}" | |||||
data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||||
</div> | </div> | ||||
<div class="ui tab active" data-tab="first{{$k}}"> | <div class="ui tab active" data-tab="first{{$k}}"> | ||||
<div style="padding-top: 10px;"> | <div style="padding-top: 10px;"> | ||||
@@ -453,7 +454,7 @@ | |||||
{{$.i18n.Tr "cloudbrain.gpu_type"}} | {{$.i18n.Tr "cloudbrain.gpu_type"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content resorce_type"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{$.resource_type}} | {{$.resource_type}} | ||||
</div> | </div> | ||||
@@ -464,9 +465,9 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content spec"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{$.resource_spec}} | |||||
{{$.resource_spec}} | |||||
</div> | </div> | ||||
</td> | </td> | ||||
</tr> | </tr> | ||||
@@ -528,19 +529,42 @@ | |||||
</div> | </div> | ||||
<div class="ui tab" data-tab="second{{$k}}"> | <div class="ui tab" data-tab="second{{$k}}"> | ||||
<div> | <div> | ||||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
<div id="header"></div> | |||||
</div> | |||||
<div class="ui attached log" id="log{{.VersionName}}" | |||||
style="height: 300px !important; overflow: auto;"> | |||||
<input type="hidden" name="end_line" value> | |||||
<input type="hidden" name="start_line" value> | |||||
<pre id="log_file{{.VersionName}}"></pre> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<a id="{{.VersionName}}-log-down" | |||||
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}}' | |||||
href="/api/v1/repos/{{$.RepoRelPath}}/cloudbrain/{{.ID}}/download_log_file"> | |||||
<i class="ri-download-cloud-2-line"></i> | |||||
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span> | |||||
</a> | |||||
</div> | |||||
<div | |||||
style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||||
<span> | |||||
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | |||||
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | |||||
</span> | |||||
<span class="log-info-{{.VersionName}}"> | |||||
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||||
class="log_bottom" data-version="{{.VersionName}}"><i | |||||
class="icon-to-bottom"></i></a> | |||||
</span> | |||||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
<div id="header"></div> | |||||
</div> | |||||
<div class="ui attached log log-scroll" id="log{{.VersionName}}" data-version="{{.VersionName}}" | |||||
style="height: 300px !important; overflow: auto;"> | |||||
<div class="ui inverted active dimmer"> | |||||
<div class="ui loader"></div> | |||||
</div> | |||||
<input type="hidden" name="end_line" value> | |||||
<input type="hidden" name="start_line" value> | |||||
<pre id="log_file{{.VersionName}}"></pre> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -571,7 +595,22 @@ | |||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{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> | <script> | ||||
$('.menu .item').tab() | $('.menu .item').tab() | ||||
@@ -606,4 +645,5 @@ | |||||
}); | }); | ||||
} | } | ||||
</script> | </script> |
@@ -82,8 +82,11 @@ | |||||
</svg> | </svg> | ||||
Ascend NPU</a> | Ascend NPU</a> | ||||
</div> | </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> | <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> | <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_infer_gpu_tooltips" "/dataset" "/model" "/result" | Safe}}</span> | ||||
</div> | </div> | ||||
@@ -140,7 +143,7 @@ | |||||
<span > | <span > | ||||
<i class="question circle icon" data-content="{{.i18n.Tr "cloudbrain.model_file_postfix_rule"}}" data-position="top center" data-variation="inverted mini"></i> | <i class="question circle icon" data-content="{{.i18n.Tr "cloudbrain.model_file_postfix_rule"}}" data-position="top center" data-variation="inverted mini"></i> | ||||
</span> | </span> | ||||
</div> | </div> | ||||
<!-- AI引擎 --> | <!-- AI引擎 --> | ||||
<div id="images-new-cb"> | <div id="images-new-cb"> | ||||
@@ -168,7 +171,7 @@ | |||||
</select> | </select> | ||||
</div> | </div> | ||||
<!-- GPU 卡的类型 --> | <!-- 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> | <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类型" | <select id="cloudbrain_gpu_type" class="ui search width48 dropdown gpu-type" placeholder="选择GPU类型" | ||||
style='width:385px' name="gpu_type"> | style='width:385px' name="gpu_type"> | ||||
@@ -189,7 +192,7 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div> | |||||
</div>--> | |||||
<!-- 数据集--> | <!-- 数据集--> | ||||
<div id="select-multi-dataset"> | <div id="select-multi-dataset"> | ||||
@@ -227,7 +230,7 @@ | |||||
</select> | </select> | ||||
</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> | <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"> | <select id="cloudbrain_resource_spec" class="ui search dropdown width80" placeholder="选择资源规格" name="resource_spec_id"> | ||||
{{if .resource_spec_id}} | {{if .resource_spec_id}} | ||||
@@ -248,8 +251,12 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required min_title inline field"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
<select id="__specs__" class="ui search dropdown width48" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" ovalue="{{.spec_id}}" name="spec_id"> | |||||
</select> | |||||
</div> | </div> | ||||
<!-- 表单操作 --> | <!-- 表单操作 --> | ||||
<div class="inline min_title field"> | <div class="inline min_title field"> | ||||
<label class="label-fix-width" style="font-weight: normal;"></label> | <label class="label-fix-width" style="font-weight: normal;"></label> | ||||
@@ -264,7 +271,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
let createFlag = false | let createFlag = false | ||||
@@ -299,7 +306,7 @@ | |||||
$('#select_model').removeClass("loading") | $('#select_model').removeClass("loading") | ||||
}) | }) | ||||
}) | }) | ||||
// 根据选中的模型名称获取相应的模型版本 | // 根据选中的模型名称获取相应的模型版本 | ||||
function modelVersion(){ | function modelVersion(){ | ||||
let faildModelVersion = $('#failed_model_version').val() | let faildModelVersion = $('#failed_model_version').val() | ||||
@@ -318,7 +325,7 @@ | |||||
$("#select_model_version").removeClass("loading") | $("#select_model_version").removeClass("loading") | ||||
const initVersionText = $('#model_name_version div.item:first-child').text() | const initVersionText = $('#model_name_version div.item:first-child').text() | ||||
const initVersionValue = $('#model_name_version div.item:first-child').data('value') | const initVersionValue = $('#model_name_version div.item:first-child').data('value') | ||||
if(faildModelVersion&&faildTrainUrl){ | if(faildModelVersion&&faildTrainUrl){ | ||||
$("#select_model_version").dropdown('set text',faildModelVersion) | $("#select_model_version").dropdown('set text',faildModelVersion) | ||||
$("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | $("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | ||||
@@ -381,7 +388,7 @@ | |||||
params&¶ms.parameter.forEach((item,index)=>{ | params&¶ms.parameter.forEach((item,index)=>{ | ||||
Add_parameter(index,flag=true,item) | Add_parameter(index,flag=true,item) | ||||
}) | }) | ||||
}) | }) | ||||
// 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
function Add_parameter(i,flag=false,paramsObject={}) { | function Add_parameter(i,flag=false,paramsObject={}) { | ||||
@@ -436,6 +443,8 @@ | |||||
msg = JSON.stringify(msg) | msg = JSON.stringify(msg) | ||||
$('#store_run_para').val(msg) | $('#store_run_para').val(msg) | ||||
} | } | ||||
var isValidate = false; | |||||
function validate(){ | function validate(){ | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -489,12 +498,18 @@ | |||||
type: 'empty', | type: 'empty', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | } | ||||
}, | }, | ||||
onSuccess: function(){ | onSuccess: function(){ | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function(e){ | onFailure: function(e){ | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -509,4 +524,15 @@ | |||||
send_run_para(); | send_run_para(); | ||||
validate(); | 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> | </script> |
@@ -228,7 +228,7 @@ | |||||
</h4> | </h4> | ||||
{{with .task}} | {{with .task}} | ||||
<div class="ui accordion border-according" id="accordion{{.VersionName}}" | <div class="ui accordion border-according" id="accordion{{.VersionName}}" | ||||
data-repopath="{{$.RepoRelPath}}/cloudbrain/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
data-repopath="{{$.RepoRelPath}}/cloudbrain" data-jobid="{{.ID}}" data-version="{{.VersionName}}"> | |||||
<input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | <input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | ||||
<div class="active title padding0"> | <div class="active title padding0"> | ||||
<div class="according-panel-heading"> | <div class="according-panel-heading"> | ||||
@@ -264,7 +264,8 @@ | |||||
data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | ||||
<a class="item" data-tab="second" | <a class="item" data-tab="second" | ||||
onclick="javascript:parseInfo()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | onclick="javascript:parseInfo()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | ||||
<a class="item log_bottom" data-tab="third" | |||||
data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||||
<a class="item load-model-file" data-tab="four" | <a class="item load-model-file" data-tab="four" | ||||
data-gpu-flag="true" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/cloudbrain/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | data-gpu-flag="true" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/cloudbrain/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | ||||
</div> | </div> | ||||
@@ -340,7 +341,7 @@ | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
{{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | {{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content resorce_type"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{$.resource_type}} | {{$.resource_type}} | ||||
</div> | </div> | ||||
@@ -482,7 +483,7 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content spec"> | |||||
<div class="text-span text-span-w"> | <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}} | {{$.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> | </div> | ||||
@@ -524,7 +525,7 @@ | |||||
<div class="ui message message{{.VersionName}}" style="display: none;"> | <div class="ui message message{{.VersionName}}" style="display: none;"> | ||||
<div id="header"></div> | <div id="header"></div> | ||||
</div> | </div> | ||||
<div class="ui attached log" id="log{{.VersionName}}" | |||||
<div class="ui attached" | |||||
style="height: 390px !important; overflow: auto;"> | style="height: 390px !important; overflow: auto;"> | ||||
<input type="hidden" id="json_value" value="{{$.result.JobStatus.AppExitDiagnostics}}"> | <input type="hidden" id="json_value" value="{{$.result.JobStatus.AppExitDiagnostics}}"> | ||||
<input type="hidden" id="ExitDiagnostics" value="{{$.ExitDiagnostics}}"> | <input type="hidden" id="ExitDiagnostics" value="{{$.ExitDiagnostics}}"> | ||||
@@ -537,7 +538,44 @@ | |||||
</div> | </div> | ||||
<div class="ui tab" data-tab="third"> | |||||
<div> | |||||
<a id="{{.VersionName}}-log-down" | |||||
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}}' | |||||
href="/api/v1/repos/{{$.RepoRelPath}}/cloudbrain/{{.ID}}/download_log_file"> | |||||
<i class="ri-download-cloud-2-line"></i> | |||||
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span> | |||||
</a> | |||||
</div> | |||||
<div | |||||
style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||||
<span> | |||||
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | |||||
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | |||||
</span> | |||||
<span class="log-info-{{.VersionName}}"> | |||||
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||||
class="log_bottom" data-version="{{.VersionName}}"><i | |||||
class="icon-to-bottom"></i></a> | |||||
</span> | |||||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
<div id="header"></div> | |||||
</div> | |||||
<div class="ui attached log log-scroll" id="log{{.VersionName}}" data-version="{{.VersionName}}" | |||||
style="height: 300px !important; overflow: auto;"> | |||||
<div class="ui inverted active dimmer"> | |||||
<div class="ui loader"></div> | |||||
</div> | |||||
<input type="hidden" name="end_line" value> | |||||
<input type="hidden" name="start_line" value> | |||||
<pre id="log_file{{.VersionName}}"></pre> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui tab" data-tab="four"> | <div class="ui tab" data-tab="four"> | ||||
<input type="hidden" name="model{{.VersionName}}" value="-1"> | <input type="hidden" name="model{{.VersionName}}" value="-1"> | ||||
@@ -561,6 +599,7 @@ | |||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
$('.menu .item').tab() | $('.menu .item').tab() | ||||
@@ -621,4 +660,17 @@ | |||||
document.getElementById("info_display").innerHTML = html; | 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> | </script> |
@@ -25,7 +25,7 @@ | |||||
<div class="column"> | <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> | <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" .}} | {{template "base/alert" .}} | ||||
<div class="ui negative message" id="messageInfo"> | |||||
<div class="ui negative message" id="messageInfo" style="display:none;"> | |||||
<p></p> | <p></p> | ||||
</div> | </div> | ||||
<form id="form_id" class="ui form" action="{{.Link}}" method="post"> | <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" /> | 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> | </svg> | ||||
Ascend NPU</a> | Ascend NPU</a> | ||||
</div> | |||||
{{template "custom/wait_count" .}} | |||||
</div> | |||||
</div> | |||||
<div class="inline field"> | |||||
<label></label> | |||||
{{template "custom/task_wait_count" .}} | |||||
</div> | </div> | ||||
<div class="inline required field"> | <div class="inline required field"> | ||||
<label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | ||||
@@ -108,8 +111,8 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div> | |||||
<div class="inline required field"> | |||||
</div> | |||||
<!--<div class="inline required field"> | |||||
<label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | <label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | ||||
<select id="cloudbrain_gpu_type" class="ui search dropdown gpu-type" placeholder="选择GPU类型" | <select id="cloudbrain_gpu_type" class="ui search dropdown gpu-type" placeholder="选择GPU类型" | ||||
style='width:385px' name="gpu_type"> | style='width:385px' name="gpu_type"> | ||||
@@ -117,7 +120,7 @@ | |||||
<option value="{{.Queue}}">{{.Value}}</option> | <option value="{{.Queue}}">{{.Value}}</option> | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div> | |||||
</div>--> | |||||
<div id="images-new-cb"> | <div id="images-new-cb"> | ||||
@@ -125,8 +128,8 @@ | |||||
<div id="select-multi-dataset"> | <div id="select-multi-dataset"> | ||||
</div> | </div> | ||||
<div class="inline required field"> | |||||
<!--<div class="inline required field"> | |||||
<label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | ||||
<select id="cloudbrain_resource_spec" class="ui search dropdown" | <select id="cloudbrain_resource_spec" class="ui search dropdown" | ||||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | ||||
@@ -137,6 +140,14 @@ | |||||
</option> | </option> | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="inline required field"> | |||||
<label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
<select id="__specs__" class="ui search dropdown" | |||||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||||
name="spec_id"> | |||||
</select> | |||||
</div> | </div> | ||||
<div class="inline required field"> | <div class="inline required field"> | ||||
@@ -188,6 +199,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
$('#messageInfo').css('display', 'none') | $('#messageInfo').css('display', 'none') | ||||
@@ -196,6 +208,7 @@ | |||||
context.value = '' | context.value = '' | ||||
$(".icon.icons").css("visibility", "hidden") | $(".icon.icons").css("visibility", "hidden") | ||||
} | } | ||||
var isValidate = false; | |||||
function validate(){ | function validate(){ | ||||
$('.ui.form').form({ | $('.ui.form').form({ | ||||
on: 'blur', | on: 'blur', | ||||
@@ -207,11 +220,17 @@ | |||||
type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | |||||
}, | }, | ||||
onSuccess: function(){ | |||||
onSuccess: function(){ | |||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function(e){ | onFailure: function(e){ | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -219,6 +238,7 @@ | |||||
validate(); | validate(); | ||||
let createFlag = false | let createFlag = false | ||||
form.onsubmit = function (e) { | form.onsubmit = function (e) { | ||||
if (!isValidate) return false; | |||||
if(createFlag) return false | if(createFlag) return false | ||||
let value_task = $("input[name='display_job_name']").val() | let value_task = $("input[name='display_job_name']").val() | ||||
let value_image = $("input[name='image']").val() | let value_image = $("input[name='image']").val() | ||||
@@ -286,7 +306,18 @@ | |||||
} | } | ||||
selected_value = $("#cloudbrain_benchmark_category").val() | selected_value = $("#cloudbrain_benchmark_category").val() | ||||
$('#store_category').attr("value", selected_value) | $('#store_category').attr("value", selected_value) | ||||
validate(); | |||||
}) | }) | ||||
;(function() { | |||||
var SPECS = {{ .debug_specs }}; | |||||
var showPoint = true; | |||||
window.renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||||
gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||||
free: {{$.i18n.Tr "cloudbrain.free"}}, | |||||
point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||||
memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||||
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||||
}); | |||||
})(); | |||||
</script> | </script> |
@@ -345,7 +345,7 @@ | |||||
{{$.i18n.Tr "cloudbrain.gpu_type"}} | {{$.i18n.Tr "cloudbrain.gpu_type"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content resorce_type"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{$.resource_type}} | {{$.resource_type}} | ||||
</div> | </div> | ||||
@@ -400,10 +400,8 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </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> | </td> | ||||
</tr> | </tr> | ||||
<tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
@@ -560,7 +558,7 @@ | |||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
$('.menu .item').tab() | $('.menu .item').tab() | ||||
$(document).ready(function () { | $(document).ready(function () { | ||||
@@ -601,4 +599,17 @@ | |||||
} | } | ||||
document.getElementById("info_display").innerHTML = html; | 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> | </script> |
@@ -14,7 +14,9 @@ | |||||
.width { | .width { | ||||
width: 100% !important; | width: 100% !important; | ||||
} | } | ||||
.width48 { | |||||
width: 48.5% !important; | |||||
} | |||||
.width80 { | .width80 { | ||||
width: 80.7% !important; | width: 80.7% !important; | ||||
margin-left: 10px; | margin-left: 10px; | ||||
@@ -30,7 +32,7 @@ | |||||
margin-left: 10.5rem !important; | margin-left: 10.5rem !important; | ||||
align-items: center; | align-items: center; | ||||
} | } | ||||
.width81 { | .width81 { | ||||
margin-left: 1.5rem !important; | margin-left: 1.5rem !important; | ||||
width: 81% !important; | width: 81% !important; | ||||
@@ -114,8 +116,11 @@ | |||||
</svg> | </svg> | ||||
Ascend NPU</a> | Ascend NPU</a> | ||||
</div> | </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> | <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> | <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/code" "/dataset" "/model" | Safe}}</span> | ||||
</div> | </div> | ||||
@@ -171,7 +176,7 @@ | |||||
<option name="job_type" value="TRAIN">TRAIN</option> | <option name="job_type" value="TRAIN">TRAIN</option> | ||||
</select> | </select> | ||||
</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.gpu_type"}}</label> | <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类型" | <select id="cloudbrain_gpu_type" class="ui search width806 dropdown gpu-type" placeholder="选择GPU类型" | ||||
style='width:385px' name="gpu_type"> | style='width:385px' name="gpu_type"> | ||||
@@ -192,7 +197,7 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div> | |||||
</div>--> | |||||
<div id="images-new-cb"> | <div id="images-new-cb"> | ||||
</div> | </div> | ||||
@@ -224,10 +229,10 @@ | |||||
class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | 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"> | <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 class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | ||||
</div> | </div> | ||||
</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> | <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="选择资源规格" | <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" | ||||
style='width:385px' name="resource_spec_id"> | style='width:385px' name="resource_spec_id"> | ||||
@@ -249,6 +254,13 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required min_title inline field"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
<select id="__specs__" class="ui dropdown width48" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" ovalue="{{.spec_id}}" | |||||
name="spec_id"> | |||||
</select> | |||||
</div> | </div> | ||||
<div class="inline field" style="padding: 1rem 0;"> | <div class="inline field" style="padding: 1rem 0;"> | ||||
@@ -267,7 +279,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
let createFlag = false | let createFlag = false | ||||
@@ -282,7 +294,7 @@ | |||||
.tab(); | .tab(); | ||||
$(document).keydown(function(event){ | $(document).keydown(function(event){ | ||||
switch(event.keyCode){ | switch(event.keyCode){ | ||||
case 13:return false; | |||||
case 13:return false; | |||||
} | } | ||||
}); | }); | ||||
$(document).ready(function(){ | $(document).ready(function(){ | ||||
@@ -290,7 +302,7 @@ | |||||
params&¶ms.parameter.forEach((item,index)=>{ | params&¶ms.parameter.forEach((item,index)=>{ | ||||
Add_parameter(index,flag=true,item) | Add_parameter(index,flag=true,item) | ||||
}) | }) | ||||
}) | }) | ||||
// 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
function Add_parameter(i,flag=false,paramsObject={}) { | function Add_parameter(i,flag=false,paramsObject={}) { | ||||
@@ -342,7 +354,8 @@ | |||||
$('select.dropdown') | $('select.dropdown') | ||||
.dropdown(); | .dropdown(); | ||||
var isValidate = false; | |||||
function validate() { | function validate() { | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -388,13 +401,19 @@ | |||||
type: 'empty', | type: 'empty', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | } | ||||
}, | }, | ||||
onSuccess: function () { | onSuccess: function () { | ||||
// $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function (e) { | onFailure: function (e) { | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -419,6 +438,17 @@ | |||||
validate(); | validate(); | ||||
$('.ui.create_train_job.green.button').click(function (e) { | $('.ui.create_train_job.green.button').click(function (e) { | ||||
send_run_para(); | send_run_para(); | ||||
validate(); | |||||
validate(); | |||||
}) | }) | ||||
</script> | |||||
;(function() { | |||||
var SPECS = {{ .train_specs }}; | |||||
var showPoint = true; | |||||
renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||||
gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||||
free: {{$.i18n.Tr "cloudbrain.free"}}, | |||||
point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||||
memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||||
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||||
}); | |||||
})(); | |||||
</script> |
@@ -359,7 +359,7 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | {{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content resorce_type"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{$.resource_type}} | {{$.resource_type}} | ||||
</div> | </div> | ||||
@@ -370,7 +370,7 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content spec"> | |||||
<div class="text-span text-span-w"> | <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}} | {{$.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> | </div> | ||||
@@ -677,6 +677,7 @@ | |||||
{{template "base/footer" .}} | {{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.core.js"></script> | ||||
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.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> | <script> | ||||
var setting = { | var setting = { | ||||
@@ -987,4 +988,17 @@ | |||||
document.getElementById("info_display").innerHTML = html; | 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> | </script> |
@@ -30,7 +30,9 @@ | |||||
.width81{ | .width81{ | ||||
width: 81% !important; | width: 81% !important; | ||||
} | } | ||||
.width48{ | |||||
width: 48.5% !important; | |||||
} | |||||
.add{font-size: 18px; | .add{font-size: 18px; | ||||
padding: 0.5rem; | padding: 0.5rem; | ||||
border: 1px solid rgba(187, 187, 187, 100); | 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"/> | <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> | </svg> | ||||
Ascend NPU</a> | 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> | <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> | <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/tmp/code" "/tmp/dataset" "/tmp/output" | Safe}}</span> | ||||
</div> | </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"> | <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> | <span class="tooltips" style="margin-left: 11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | ||||
</div> | </div> | ||||
<div class="min_title inline field"> | <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> | <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | ||||
{{if .description}} | {{if .description}} | ||||
@@ -128,7 +133,7 @@ | |||||
<div class="ui divider"></div> | <div class="ui divider"></div> | ||||
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | ||||
<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 "repo.modelarts.code_version"}}</label> | <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> | <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> | </div> | ||||
{{template "custom/select_dataset_train" .}} | {{template "custom/select_dataset_train" .}} | ||||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | ||||
<div class="inline min_title field"> | <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> | <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"> | <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 class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | ||||
</div> | </div> | ||||
</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> | <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"> | <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | ||||
{{if .flavor}} | {{if .flavor}} | ||||
@@ -199,8 +203,12 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required min_title inline field" id="flavor_name"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||||
<select class="ui dropdown width48" id="__specs__" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||||
</div> | </div> | ||||
<div class="inline min_title field"> | <div class="inline min_title field"> | ||||
<label class="label-fix-width"></label> | <label class="label-fix-width"></label> | ||||
<button class="ui create_train_job green button"> | <button class="ui create_train_job green button"> | ||||
@@ -208,14 +216,15 @@ | |||||
</button> | </button> | ||||
<a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | <a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | ||||
</div> | </div> | ||||
<!-- 模态框 --> | <!-- 模态框 --> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
@@ -230,13 +239,13 @@ | |||||
$('.menu .item') | $('.menu .item') | ||||
.tab(); | .tab(); | ||||
$(document).ready(function(){ | $(document).ready(function(){ | ||||
let params = $('.dynamic.field').data('params') | let params = $('.dynamic.field').data('params') | ||||
params&¶ms.parameter.forEach((item,index)=>{ | params&¶ms.parameter.forEach((item,index)=>{ | ||||
Add_parameter(index,flag=true,item) | Add_parameter(index,flag=true,item) | ||||
}) | }) | ||||
}) | }) | ||||
// 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
function Add_parameter(i,flag=false,paramsObject={}) { | function Add_parameter(i,flag=false,paramsObject={}) { | ||||
@@ -287,6 +296,7 @@ | |||||
$('select.dropdown') | $('select.dropdown') | ||||
.dropdown(); | .dropdown(); | ||||
var isValidate = false; | |||||
function validate(){ | function validate(){ | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -333,13 +343,19 @@ | |||||
type : 'integer[1..25]', | type : 'integer[1..25]', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | } | ||||
}, | }, | ||||
onSuccess: function(){ | onSuccess: function(){ | ||||
// $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function(e){ | |||||
onFailure: function(e){ | |||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -374,4 +390,16 @@ | |||||
send_run_para() | send_run_para() | ||||
validate(); | validate(); | ||||
}) | }) | ||||
</script> | |||||
;(function() { | |||||
var SPECS = {{ .Specs }}; | |||||
var showPoint = true; | |||||
renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||||
gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||||
free: {{$.i18n.Tr "cloudbrain.free"}}, | |||||
point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||||
memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||||
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||||
}); | |||||
})(); | |||||
</script> |
@@ -25,7 +25,9 @@ | |||||
.width81{ | .width81{ | ||||
width: 81% !important; | width: 81% !important; | ||||
} | } | ||||
.width48 { | |||||
width: 48.5% !important; | |||||
} | |||||
.add{font-size: 18px; | .add{font-size: 18px; | ||||
padding: 0.5rem; | padding: 0.5rem; | ||||
border: 1px solid rgba(187, 187, 187, 100); | border: 1px solid rgba(187, 187, 187, 100); | ||||
@@ -99,13 +101,15 @@ | |||||
</svg> | </svg> | ||||
Ascend NPU</a> | Ascend NPU</a> | ||||
</div> | </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> | <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> | <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> | </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 "repo.modelarts.train_job.job_name"}}</label> | <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"> | <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> | </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> | <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> | </div> | ||||
{{template "custom/select_dataset_train" .}} | {{template "custom/select_dataset_train" .}} | ||||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | ||||
<div class="inline min_title field"> | <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> | <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"> | <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 class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | ||||
</div> | </div> | ||||
</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> | <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"> | <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | ||||
{{if .flavor}} | {{if .flavor}} | ||||
@@ -211,6 +215,10 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required min_title inline field" id="flavor_name"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||||
<select class="ui dropdown width48" id="__specs__" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||||
</div> | </div> | ||||
<div class="inline required min_title field"> | <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> | <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> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
@@ -256,13 +265,13 @@ | |||||
$('.menu .item') | $('.menu .item') | ||||
.tab(); | .tab(); | ||||
$(document).ready(function(){ | $(document).ready(function(){ | ||||
let params = $('.dynamic.field').data('params') | let params = $('.dynamic.field').data('params') | ||||
params&¶ms.parameter.forEach((item,index)=>{ | params&¶ms.parameter.forEach((item,index)=>{ | ||||
Add_parameter(index,flag=true,item) | Add_parameter(index,flag=true,item) | ||||
}) | }) | ||||
}) | }) | ||||
// 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
function Add_parameter(i,flag=false,paramsObject={}) { | function Add_parameter(i,flag=false,paramsObject={}) { | ||||
@@ -309,10 +318,11 @@ | |||||
$(this).popup('show') | $(this).popup('show') | ||||
}); | }); | ||||
$('select.dropdown') | $('select.dropdown') | ||||
.dropdown(); | .dropdown(); | ||||
var isValidate = false; | |||||
function validate(){ | function validate(){ | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -350,13 +360,19 @@ | |||||
type : 'integer[1..25]', | type : 'integer[1..25]', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | } | ||||
}, | }, | ||||
onSuccess: function(){ | onSuccess: function(){ | ||||
// $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function(e){ | onFailure: function(e){ | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -395,4 +411,16 @@ | |||||
send_run_para() | send_run_para() | ||||
validate(); | 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> | </script> |
@@ -357,7 +357,7 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content spec"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{.FlavorName}} | {{.FlavorName}} | ||||
</div> | </div> | ||||
@@ -634,8 +634,20 @@ | |||||
{{template "base/footer" .}} | {{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.core.js"></script> | ||||
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.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> | <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 = { | var setting = { | ||||
check: { | check: { | ||||
enable: true, | enable: true, | ||||
@@ -83,8 +83,11 @@ | |||||
</svg> | </svg> | ||||
Ascend NPU</a> | Ascend NPU</a> | ||||
</div> | </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> | <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> | <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.infer_dataset_path_rule" | Safe}}</span> | ||||
</div> | </div> | ||||
@@ -196,7 +199,7 @@ | |||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div> | </div> | ||||
<!-- 数据集 --> | <!-- 数据集 --> | ||||
<div id="select-multi-dataset"> | <div id="select-multi-dataset"> | ||||
@@ -249,7 +252,7 @@ | |||||
</select> | </select> | ||||
</div> | </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> | <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"> | <select class="ui dropdown width80" id="trainjob-flavor" name="flavor"> | ||||
{{if .flavor}} | {{if .flavor}} | ||||
@@ -269,6 +272,10 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required min_title inline field" id="flaver_name"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||||
<select class="ui dropdown width48" id="__specs__" name="spec_id" ovalue="{{.spec_id}}"></select> | |||||
</div> | </div> | ||||
<!-- 计算节点 --> | <!-- 计算节点 --> | ||||
<div class="inline required min_title field"> | <div class="inline required min_title field"> | ||||
@@ -292,7 +299,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
let createFlag = false | let createFlag = false | ||||
@@ -305,7 +312,7 @@ | |||||
let nameMap,nameList | let nameMap,nameList | ||||
$(".ui.button").attr('href',url_href) | $(".ui.button").attr('href',url_href) | ||||
// 获取模型列表和模型名称对应的模型版本 | // 获取模型列表和模型名称对应的模型版本 | ||||
$(document).ready(function(){ | $(document).ready(function(){ | ||||
modelVersion() | modelVersion() | ||||
modelCkpt() | modelCkpt() | ||||
@@ -330,7 +337,7 @@ | |||||
$('#select_model').removeClass("loading") | $('#select_model').removeClass("loading") | ||||
}) | }) | ||||
}) | }) | ||||
// 根据选中的模型名称获取相应的模型版本 | // 根据选中的模型名称获取相应的模型版本 | ||||
function modelVersion(){ | function modelVersion(){ | ||||
let faildModelVersion = $('#failed_model_version').val() | let faildModelVersion = $('#failed_model_version').val() | ||||
@@ -349,7 +356,7 @@ | |||||
$("#select_model_version").removeClass("loading") | $("#select_model_version").removeClass("loading") | ||||
const initVersionText = $('#model_name_version div.item:first-child').text() | const initVersionText = $('#model_name_version div.item:first-child').text() | ||||
const initVersionValue = $('#model_name_version div.item:first-child').data('value') | const initVersionValue = $('#model_name_version div.item:first-child').data('value') | ||||
if(faildModelVersion&&faildTrainUrl){ | if(faildModelVersion&&faildTrainUrl){ | ||||
$("#select_model_version").dropdown('set text',faildModelVersion) | $("#select_model_version").dropdown('set text',faildModelVersion) | ||||
$("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | $("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | ||||
@@ -458,6 +465,8 @@ | |||||
$("input#ai_engine_name").val(name1) | $("input#ai_engine_name").val(name1) | ||||
$("input#ai_flaver_name").val(name2) | $("input#ai_flaver_name").val(name2) | ||||
} | } | ||||
var isValidate = false; | |||||
function validate(){ | function validate(){ | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -511,12 +520,18 @@ | |||||
type: 'empty', | type: 'empty', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | } | ||||
}, | }, | ||||
onSuccess: function(){ | onSuccess: function(){ | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function(e){ | onFailure: function(e){ | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -532,4 +547,16 @@ | |||||
get_name() | get_name() | ||||
validate(); | 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> | </script> |
@@ -423,7 +423,7 @@ td, th { | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content spec"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{.FlavorName}} | {{.FlavorName}} | ||||
</div> | </div> | ||||
@@ -522,6 +522,7 @@ td, th { | |||||
<!-- 确认模态框 --> | <!-- 确认模态框 --> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
console.log('{{$.canDownload}}') | console.log('{{$.canDownload}}') | ||||
$(document).ready(function(){ | $(document).ready(function(){ | ||||
@@ -538,5 +539,17 @@ $(document).ready(function(){ | |||||
repoPath = urlArr.slice(-4)[0] | repoPath = urlArr.slice(-4)[0] | ||||
jobID = urlArr.slice(-1)[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> | </script> |
@@ -38,7 +38,10 @@ | |||||
</svg> | </svg> | ||||
Ascend NPU</a> | Ascend NPU</a> | ||||
</div> | </div> | ||||
{{template "custom/wait_count" .}} | |||||
</div> | |||||
<div class="inline field"> | |||||
<label></label> | |||||
{{template "custom/task_wait_count" .}} | |||||
</div> | </div> | ||||
<div class="inline required field"> | <div class="inline required field"> | ||||
<label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | ||||
@@ -65,7 +68,7 @@ | |||||
<label>类型</label> | <label>类型</label> | ||||
<input name="job_type" id="cloudbrain_job_type" value="{{.notebook_type}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="job_type" id="cloudbrain_job_type" value="{{.notebook_type}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
</div> --> | </div> --> | ||||
<div class="inline required field"> | |||||
<!--<div class="inline required field"> | |||||
<label>{{.i18n.Tr "cloudbrain.specification"}}</label> | <label>{{.i18n.Tr "cloudbrain.specification"}}</label> | ||||
<select id="cloudbrain_flavor" class="ui search dropdown" placeholder="选择规格" style='width:385px' name="flavor"> | <select id="cloudbrain_flavor" class="ui search dropdown" placeholder="选择规格" style='width:385px' name="flavor"> | ||||
{{range .flavors}} | {{range .flavors}} | ||||
@@ -73,6 +76,10 @@ | |||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="inline required field"> | |||||
<label>{{.i18n.Tr "cloudbrain.specification"}}</label> | |||||
<select id="__specs__" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||||
</div> | </div> | ||||
<!--<div class="inline required field"> | <!--<div class="inline required field"> | ||||
<label>数据集存放路径</label> | <label>数据集存放路径</label> | ||||
@@ -95,13 +102,14 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
// 判断必填选项是否填写正确 | // 判断必填选项是否填写正确 | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
$('#messageInfo').css('display','none') | $('#messageInfo').css('display','none') | ||||
var isValidate = false; | |||||
function validate(){ | function validate(){ | ||||
$('.ui.form').form({ | $('.ui.form').form({ | ||||
on: 'blur', | on: 'blur', | ||||
@@ -113,11 +121,17 @@ | |||||
type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | |||||
}, | }, | ||||
onSuccess: function(){ | |||||
onSuccess: function(){ | |||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function(e){ | onFailure: function(e){ | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -125,7 +139,8 @@ | |||||
validate(); | validate(); | ||||
let createFlag = false | let createFlag = false | ||||
form.onsubmit = function(e){ | form.onsubmit = function(e){ | ||||
if(createFlag) return false | |||||
if(!isValidate) return false; | |||||
if(createFlag) return false; | |||||
let value_task = $("input[name='display_job_name']").val() | let value_task = $("input[name='display_job_name']").val() | ||||
let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | ||||
let flag = re.test(value_task) | let flag = re.test(value_task) | ||||
@@ -171,4 +186,16 @@ | |||||
} | } | ||||
}); | }); | ||||
}); | }); | ||||
;(function() { | |||||
var SPECS = {{ .Specs }}; | |||||
var showPoint = true; | |||||
renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||||
gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||||
free: {{$.i18n.Tr "cloudbrain.free"}}, | |||||
point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||||
memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||||
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||||
}); | |||||
})(); | |||||
</script> | </script> |
@@ -350,14 +350,14 @@ | |||||
<td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <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-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-error="{{$.i18n.Tr "repo.copy_link_error"}}" | ||||
data-content="{{$.i18n.Tr "repo.copy_link"}}" | data-content="{{$.i18n.Tr "repo.copy_link"}}" | ||||
data-variation="inverted tiny" | data-variation="inverted tiny" | ||||
> | > | ||||
<span title="{{.Image}}">{{.Image}}</span> | |||||
<span title="{{.Image}}">{{.Image}}</span> | |||||
</span> | </span> | ||||
</div> | </div> | ||||
</td> | </td> | ||||
@@ -367,7 +367,7 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content spec"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{$.resource_spec}} | {{$.resource_spec}} | ||||
</div> | </div> | ||||
@@ -427,7 +427,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div style="clear:both"> | <div style="clear:both"> | ||||
<table style="border:none" class="ui fixed small stackable table"> | <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> | <th style="color: #8a8e99;font-size:12px" class="two wide center aligned">{{$.i18n.Tr "dataset.download_oper"}}</th> | ||||
</tr></thead> | </tr></thead> | ||||
<tbody> | <tbody> | ||||
{{range $.datasetDownload}} | |||||
{{range $.datasetDownload}} | |||||
<tr> | <tr> | ||||
<td style="word-wrap: break-word;word-break: break-all;"> | <td style="word-wrap: break-word;word-break: break-all;"> | ||||
@@ -488,7 +488,7 @@ | |||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
$('.menu .item').tab() | $('.menu .item').tab() | ||||
@@ -498,4 +498,19 @@ | |||||
$(document).ready(function () { | $(document).ready(function () { | ||||
$('.secondary.menu .item').tab(); | $('.secondary.menu .item').tab(); | ||||
}); | }); | ||||
</script> | |||||
console.log({{$.datasetDownload}}) | |||||
;(function() { | |||||
var SPEC = {{ .Spec }}; | |||||
var showPoint = true; | |||||
var specStr = window.renderSpecStr(SPEC, showPoint, { | |||||
gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||||
free: {{$.i18n.Tr "cloudbrain.free"}}, | |||||
point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||||
memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||||
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||||
}); | |||||
$('td.ti-text-form-content.spec div').text(specStr); | |||||
$('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||||
})(); | |||||
</script> |
@@ -88,7 +88,7 @@ | |||||
</a> | </a> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="required inline min_title field"> | <div class="required inline min_title field"> | ||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | ||||
<div class="ui blue mini menu compact selectcloudbrain"> | <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" /> | 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> | </svg> | ||||
Ascend NPU</a> | 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> | <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> | <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.train_dataset_path_rule" | Safe}}</span> | ||||
</div> | </div> | ||||
@@ -203,7 +206,7 @@ | |||||
</span> | </span> | ||||
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | ||||
</div> | </div> | ||||
<div id="select-multi-dataset"> | <div id="select-multi-dataset"> | ||||
</div> | </div> | ||||
@@ -257,7 +260,7 @@ | |||||
</div> | </div> | ||||
</div> | </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> | <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"> | <select class="ui dropdown width48" id="trainjob-flavor" name="flavor"> | ||||
{{if .flavor}} | {{if .flavor}} | ||||
@@ -277,6 +280,10 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required inline min_title field" id="flaver_name"> | |||||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||||
<select class="ui dropdown width48" id="__specs__" name="spec_id" ovalue="{{.spec_id}}"></select> | |||||
</div> | </div> | ||||
<div class="inline required min_title field"> | <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> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | ||||
@@ -287,8 +294,24 @@ | |||||
id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" | id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" | ||||
readonly> | readonly> | ||||
<div class="field" id="trainjob_work_server_num_select" name="work_server_number_select"> | <div class="field" id="trainjob_work_server_num_select" name="work_server_number_select"> | ||||
<select class="ui dropdown width" style='width: 100%;' name="work_server_id"> | |||||
<select class="ui dropdown width" style='width: 100%;' name="work_server_id"> | |||||
{{if .WorkNode}} | |||||
{{range .WorkNode}} | |||||
{{if $.work_server_number}} | |||||
{{if eq . $.work_server_number }} | |||||
<option name="server_id" selected value="{{.}}">{{.}}</option> | |||||
{{else}} | |||||
<option name="server_id" value="{{.}}">{{.}}</option> | |||||
{{end}} | |||||
{{else}} | |||||
<option name="server_id" value="{{.}}">{{.}}</option> | |||||
{{end}} | |||||
{{end}} | |||||
{{else}} | |||||
<option name="server_id" value="1">1</option> | <option name="server_id" value="1">1</option> | ||||
{{end}} | |||||
</select> | </select> | ||||
</div> | </div> | ||||
@@ -310,7 +333,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let form = document.getElementById('form_id'); | let form = document.getElementById('form_id'); | ||||
let createFlag = false | let createFlag = false | ||||
@@ -327,7 +350,7 @@ | |||||
.tab(); | .tab(); | ||||
$(document).keydown(function(event){ | $(document).keydown(function(event){ | ||||
switch(event.keyCode){ | switch(event.keyCode){ | ||||
case 13:return false; | |||||
case 13:return false; | |||||
} | } | ||||
}); | }); | ||||
// 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
@@ -441,6 +464,7 @@ | |||||
$('select.dropdown') | $('select.dropdown') | ||||
.dropdown(); | .dropdown(); | ||||
var isValidate = false; | |||||
function validate() { | function validate() { | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -478,13 +502,19 @@ | |||||
type: 'integer[1..25]', | type: 'integer[1..25]', | ||||
} | } | ||||
] | ] | ||||
}, | |||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | } | ||||
}, | }, | ||||
onSuccess: function () { | onSuccess: function () { | ||||
// $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function (e) { | onFailure: function (e) { | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -523,4 +553,16 @@ | |||||
send_run_para(); | send_run_para(); | ||||
validate(); | validate(); | ||||
}) | }) | ||||
</script> | |||||
;(function() { | |||||
var SPECS = {{ .Specs }}; | |||||
var showPoint = true; | |||||
renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||||
gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||||
free: {{$.i18n.Tr "cloudbrain.free"}}, | |||||
point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||||
memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||||
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||||
}); | |||||
})(); | |||||
</script> |
@@ -1,5 +1,7 @@ | |||||
{{template "base/head" .}} | {{template "base/head" .}} | ||||
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css"> | <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> | <style> | ||||
.according-panel-heading { | .according-panel-heading { | ||||
box-sizing: border-box; | box-sizing: border-box; | ||||
@@ -395,11 +397,26 @@ | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | ||||
</td> | </td> | ||||
<td class="ti-text-form-content"> | |||||
<td class="ti-text-form-content spec{{$k}}"> | |||||
<div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
{{.FlavorName}} | {{.FlavorName}} | ||||
</div> | </div> | ||||
</td> | </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> | </tr> | ||||
</tbody> | </tbody> | ||||
@@ -73,7 +73,6 @@ | |||||
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> | <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="ai_flaver_name" name="flaver_names" value=""> | ||||
<input type="hidden" id="display_job_name" name="display_job_name" value="{{.display_job_name}}"> | <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> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
<div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
<label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | <label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | ||||
@@ -108,12 +107,12 @@ | |||||
d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | 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> | </svg> | ||||
Ascend NPU</a> | Ascend NPU</a> | ||||
</div> | |||||
</div> | |||||
</div> | </div> | ||||
<div style="margin-top:-5px;"> | |||||
{{template "custom/wait_count_train" Dict "ctx" $}} | |||||
<div style="display: flex;align-items: center;margin-left: 156px;margin-top: -0.5rem;"> | |||||
{{template "custom/task_wait_count" .}} | |||||
</div> | </div> | ||||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;margin-bottom: 1.5rem;"> | |||||
<div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;margin-bottom: 1.5rem;"> | |||||
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | <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> | <span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.train_dataset_path_rule" | Safe}}</span> | ||||
</div> | </div> | ||||
@@ -249,7 +248,7 @@ | |||||
</div> | </div> | ||||
</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> | <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"> | <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | ||||
{{if .flavor_name}} | {{if .flavor_name}} | ||||
@@ -261,6 +260,10 @@ | |||||
{{end}} | {{end}} | ||||
{{end}} | {{end}} | ||||
</select> | </select> | ||||
</div>--> | |||||
<div class="required unite min_title inline field" id="flaver_name"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||||
<select id="__specs__" class="ui dropdown width81" style='width:385px' name="spec_id" ovalue="{{.spec_id}}"></select> | |||||
</div> | </div> | ||||
<div class="inline required unite min_title field"> | <div class="inline required unite min_title field"> | ||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | ||||
@@ -287,6 +290,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<script> | <script> | ||||
let url_href = location.pathname.split('/create_version')[0] | let url_href = location.pathname.split('/create_version')[0] | ||||
@@ -427,53 +431,7 @@ | |||||
$('select.dropdown') | $('select.dropdown') | ||||
.dropdown(); | .dropdown(); | ||||
$('.ui.form') | |||||
.form({ | |||||
on: 'blur', | |||||
inline:true, | |||||
fields: { | |||||
boot_file: { | |||||
identifier : 'boot_file', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/.+\.py$/g]', | |||||
prompt : '启动文件必须为.py结尾' | |||||
} | |||||
] | |||||
}, | |||||
job_name:{ | |||||
identifier : 'job_name', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||||
prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||||
} | |||||
] | |||||
}, | |||||
display_job_name:{ | |||||
identifier : 'display_job_name', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||||
prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||||
} | |||||
] | |||||
}, | |||||
attachment:{ | |||||
identifier : 'attachment', | |||||
rules: [ | |||||
{ | |||||
type: 'empty', | |||||
prompt : '选择一个数据集' | |||||
} | |||||
] | |||||
}, | |||||
}, | |||||
}) | |||||
var isValidate = false; | |||||
function validate(){ | function validate(){ | ||||
$('.ui.form') | $('.ui.form') | ||||
.form({ | .form({ | ||||
@@ -517,12 +475,18 @@ | |||||
] | ] | ||||
}, | }, | ||||
spec_id: { | |||||
identifier: 'spec_id', | |||||
rules: [{ type: 'empty' }] | |||||
} | |||||
}, | }, | ||||
onSuccess: function(){ | onSuccess: function(){ | ||||
// $('.ui.page.dimmer').dimmer('show') | // $('.ui.page.dimmer').dimmer('show') | ||||
document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
isValidate = true; | |||||
}, | }, | ||||
onFailure: function(e){ | onFailure: function(e){ | ||||
isValidate = false; | |||||
return false; | return false; | ||||
} | } | ||||
}) | }) | ||||
@@ -553,9 +517,22 @@ | |||||
} | } | ||||
validate() | |||||
$('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
get_name() | get_name() | ||||
send_run_para() | send_run_para() | ||||
validate() | 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> | </script> |
@@ -1,5 +1,6 @@ | |||||
{{template "base/head" .}} | {{template "base/head" .}} | ||||
<!-- 提示框 --> | <!-- 提示框 --> | ||||
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||||
<div class="alert"></div> | <div class="alert"></div> | ||||
<div class="explore users"> | <div class="explore users"> | ||||
<div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" | <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" | ||||
@@ -159,11 +160,17 @@ | |||||
</div> | </div> | ||||
<!-- XPU类型 --> | <!-- XPU类型 --> | ||||
<div class="one wide column text center nowrap" style="width:10% !important;"> | <div class="one wide column text center nowrap" style="width:10% !important;"> | ||||
<span style="font-size: 12px;" title="{{.CardType}}"> | |||||
{{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||||
</span> | |||||
</div> | |||||
<span style="font-size: 12px;" title="" class="card_type_{{.DisplayJobName}}_{{$JobID}}"></span> | |||||
</div> | |||||
<script> | |||||
(function(){ | |||||
var spec = {{.Spec}} || {}; | |||||
var cardType = getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType) || '--'; | |||||
var spanEl = document.querySelector('.card_type_{{.DisplayJobName}}_{{$JobID}}'); | |||||
spanEl.setAttribute('title', cardType); | |||||
spanEl.innerText = cardType; | |||||
})(); | |||||
</script> | |||||
<!-- 项目 --> | <!-- 项目 --> | ||||
<div class="two wide column text center nowrap" style="width: 11%!important;"> | <div class="two wide column text center nowrap" style="width: 11%!important;"> | ||||
<a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | ||||
@@ -0,0 +1,31 @@ | |||||
window.ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'ASCEND910', v: 'Ascend 910' }, { k: 'MLU270', v: 'MLU270' }, { k: 'RTX3080', v: 'RTX3080' }]; | |||||
window.getListValueWithKey = (list, key, k = 'k', v = 'v', defaultV = '') => { | |||||
for (let i = 0, iLen = list.length; i < iLen; i++) { | |||||
const listI = list[i]; | |||||
if (listI[k] === key) return listI[v]; | |||||
} | |||||
return defaultV; | |||||
}; | |||||
window.renderSpecStr = (spec, showPoint, langObj) => { | |||||
showPoint = false; | |||||
var ngpu = `${spec.ComputeResource}: ${spec.AccCardsNum + '*' + getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType)}`; | |||||
var gpuMemStr = spec.GPUMemGiB != 0 ? `${langObj.gpu_memory}: ${spec.GPUMemGiB}GB, ` : ''; | |||||
var sharedMemStr = spec.ShareMemGiB != 0 ? `, ${langObj.shared_memory}: ${spec.ShareMemGiB}GB` : ''; | |||||
var pointStr = showPoint ? `, ${spec.UnitPrice == 0 ? langObj.free : spec.UnitPrice + langObj.point_hr}` : ''; | |||||
var specStr = `${ngpu}, CPU: ${spec.CpuCores}, ${gpuMemStr}${langObj.memory}: ${spec.MemGiB}GB${sharedMemStr}${pointStr}`; | |||||
return specStr; | |||||
}; | |||||
window.renderSpecsSelect = (specsSel, data, showPoint, langObj) => { | |||||
specsSel.empty(); | |||||
data = data || []; | |||||
var oValue = specsSel.attr('ovalue'); | |||||
for (var i = 0, iLen = data.length; i < iLen; i++) { | |||||
var spec = data[i]; | |||||
var specStr = window.renderSpecStr(spec, showPoint, langObj); | |||||
specsSel.append(`<option name="spec_id" value="${spec.ID}" queueCode="${spec.QueueCode}">${specStr}</option>`); | |||||
} | |||||
oValue && specsSel.val(oValue); | |||||
} |
@@ -10,7 +10,7 @@ export const JOB_TYPE = [{ k: 'DEBUG', v: i18n.t('debugTask') }, { k: 'TRAIN', v | |||||
// 资源管理 | // 资源管理 | ||||
export const CLUSTERS = [{ k: 'OpenI', v: i18n.t('resourcesManagement.OpenI') }, { k: 'C2Net', v: i18n.t('resourcesManagement.C2Net') }]; | export const CLUSTERS = [{ k: 'OpenI', v: i18n.t('resourcesManagement.OpenI') }, { k: 'C2Net', v: i18n.t('resourcesManagement.C2Net') }]; | ||||
export const AI_CENTER = [{ k: 'OpenIOne', v: i18n.t('resourcesManagement.OpenIOne') }, { k: 'OpenITwo', v: i18n.t('resourcesManagement.OpenITwo') }, { k: 'chendu', v: i18n.t('resourcesManagement.chenduCenter') }, { k: 'pclcci', v: i18n.t('resourcesManagement.pclcci') }, { k: 'hefei', v: i18n.t('resourcesManagement.hefeiCenter') }, { k: 'xuchang', v: i18n.t('resourcesManagement.xuchangCenter') }]; | |||||
export const AI_CENTER = [{ k: 'OpenIOne', v: i18n.t('resourcesManagement.OpenIOne') }, { k: 'OpenITwo', v: i18n.t('resourcesManagement.OpenITwo') }, { k: 'OpenIChengdu', v: i18n.t('resourcesManagement.OpenIChengdu') }, { k: 'pclcci', v: i18n.t('resourcesManagement.pclcci') }, { k: 'hefei', v: i18n.t('resourcesManagement.hefeiCenter') }, { k: 'xuchang', v: i18n.t('resourcesManagement.xuchangCenter') }]; | |||||
export const COMPUTER_RESOURCES = [{ k: 'GPU', v: 'GPU' }, { k: 'NPU', v: 'NPU' }, { k: 'MLU', v: 'MLU' }]; | export const COMPUTER_RESOURCES = [{ k: 'GPU', v: 'GPU' }, { k: 'NPU', v: 'NPU' }, { k: 'MLU', v: 'MLU' }]; | ||||
export const ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'ASCEND910', v: 'Ascend 910' }, { k: 'MLU270', v: 'MLU270' }, { k: 'RTX3080', v: 'RTX3080' }]; | export const ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'ASCEND910', v: 'Ascend 910' }, { k: 'MLU270', v: 'MLU270' }, { k: 'RTX3080', v: 'RTX3080' }]; | ||||
export const SPECIFICATION_STATUS = [{ k: '1', v: i18n.t('resourcesManagement.willOnShelf') }, { k: '2', v: i18n.t('resourcesManagement.onShelf') }, { k: '3', v: i18n.t('resourcesManagement.offShelf') }]; | export const SPECIFICATION_STATUS = [{ k: '1', v: i18n.t('resourcesManagement.willOnShelf') }, { k: '2', v: i18n.t('resourcesManagement.onShelf') }, { k: '3', v: i18n.t('resourcesManagement.offShelf') }]; |
@@ -82,7 +82,8 @@ const en = { | |||||
C2Net: 'C2Net', | C2Net: 'C2Net', | ||||
OpenIOne: 'OpenI One', | OpenIOne: 'OpenI One', | ||||
OpenITwo: 'OpenI Two', | OpenITwo: 'OpenI Two', | ||||
chenduCenter: 'ChenDu AI Center', | |||||
OpenIChengdu: 'OpenI ChengDu AI Chenter', | |||||
chengduCenter: 'ChengDu AI Center', | |||||
pclcci: 'PCL Cloud Computer Institute', | pclcci: 'PCL Cloud Computer Institute', | ||||
hefeiCenter: 'HeFei AI Center', | hefeiCenter: 'HeFei AI Center', | ||||
xuchangCenter: 'XuChang AI Center', | xuchangCenter: 'XuChang AI Center', | ||||
@@ -131,6 +132,7 @@ const en = { | |||||
onShelfConfirm: 'Are you sure to on shelf the resources specification?', | onShelfConfirm: 'Are you sure to on shelf the resources specification?', | ||||
offShelfConfirm: 'Are you sure to off shelf the resources specification?', | offShelfConfirm: 'Are you sure to off shelf the resources specification?', | ||||
onShelfCode1001: 'On shelf failed, the resources queues not available.', | onShelfCode1001: 'On shelf failed, the resources queues not available.', | ||||
onShelfCode1003: 'On shelf failed, the resources specification not available.', | |||||
offShelfDlgTip1: 'The resources specification has already used in scene:', | offShelfDlgTip1: 'The resources specification has already used in scene:', | ||||
offShelfDlgTip2: 'Please confirm to off shelf?', | offShelfDlgTip2: 'Please confirm to off shelf?', | ||||
resSceneManagement: 'Resources Scene Management', | resSceneManagement: 'Resources Scene Management', | ||||
@@ -149,7 +151,11 @@ const en = { | |||||
computeCluster: 'Compute Cluster', | computeCluster: 'Compute Cluster', | ||||
resourceSpecification: 'Resource Specification', | resourceSpecification: 'Resource Specification', | ||||
lastUpdateTime: 'Last Update Time', | lastUpdateTime: 'Last Update Time', | ||||
resSceneDeleteConfirm: 'Are you sure to delete the current Resource Scene?', | |||||
resSceneDeleteConfirm: 'Are you sure to delete the current Resource Scene?', | |||||
resourceSpecificationIsAvailable: 'Specification Is Available', | |||||
resourceSpecificationIsAvailableAll: 'Specification Is Available(All)', | |||||
available: 'Available', | |||||
notAvailable: 'Not Available', | |||||
}, | }, | ||||
} | } | ||||
@@ -82,7 +82,8 @@ const zh = { | |||||
C2Net: '智算集群', | C2Net: '智算集群', | ||||
OpenIOne: '云脑一', | OpenIOne: '云脑一', | ||||
OpenITwo: '云脑二', | OpenITwo: '云脑二', | ||||
chenduCenter: '成都人工智能计算中心', | |||||
OpenIChengdu: '启智成都智算', | |||||
chengduCenter: '成都智算', | |||||
pclcci: '鹏城云计算所', | pclcci: '鹏城云计算所', | ||||
hefeiCenter: '合肥类脑类脑智能开放平台', | hefeiCenter: '合肥类脑类脑智能开放平台', | ||||
xuchangCenter: '中原人工智能计算中心', | xuchangCenter: '中原人工智能计算中心', | ||||
@@ -131,6 +132,7 @@ const zh = { | |||||
onShelfConfirm: '请确认上架该规格?', | onShelfConfirm: '请确认上架该规格?', | ||||
offShelfConfirm: '请确认下架该规格?', | offShelfConfirm: '请确认下架该规格?', | ||||
onShelfCode1001: '上架失败,资源池(队列)不可用。', | onShelfCode1001: '上架失败,资源池(队列)不可用。', | ||||
onShelfCode1003: '上架失败,资源规格不可用。', | |||||
offShelfDlgTip1: '当前资源规格已在以下场景中使用:', | offShelfDlgTip1: '当前资源规格已在以下场景中使用:', | ||||
offShelfDlgTip2: '请确认进行下架操作?', | offShelfDlgTip2: '请确认进行下架操作?', | ||||
resSceneManagement: '算力资源应用场景管理', | resSceneManagement: '算力资源应用场景管理', | ||||
@@ -150,6 +152,10 @@ const zh = { | |||||
resourceSpecification: '资源规格', | resourceSpecification: '资源规格', | ||||
lastUpdateTime: '最后更新时间', | lastUpdateTime: '最后更新时间', | ||||
resSceneDeleteConfirm: '是否确认删除当前应用场景?', | resSceneDeleteConfirm: '是否确认删除当前应用场景?', | ||||
resourceSpecificationIsAvailable: '资源规格是否可用', | |||||
resourceSpecificationIsAvailableAll: '资源规格是否可用(全部)', | |||||
available: '可用', | |||||
notAvailable: '不可用', | |||||
}, | }, | ||||
} | } | ||||
@@ -10,7 +10,8 @@ | |||||
<span>{{ $t('resourcesManagement.resQueueName') }}</span> | <span>{{ $t('resourcesManagement.resQueueName') }}</span> | ||||
</div> | </div> | ||||
<div class="content"> | <div class="content"> | ||||
<el-input v-model="dataInfo.QueueCode" placeholder="" :disabled="type === 'edit'" maxlength="255"></el-input> | |||||
<el-input v-model="dataInfo.QueueCode" placeholder="" :disabled="type === 'edit'" maxlength="255"> | |||||
</el-input> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-row"> | <div class="form-row"> | ||||
@@ -101,7 +102,7 @@ export default { | |||||
return { | return { | ||||
dialogShow: false, | dialogShow: false, | ||||
clusterList: [CLUSTERS[0]], | clusterList: [CLUSTERS[0]], | ||||
computingCenterList: [AI_CENTER[0], AI_CENTER[1]], | |||||
computingCenterList: [AI_CENTER[0], AI_CENTER[1], AI_CENTER[2]], | |||||
computingTypeList: [...COMPUTER_RESOURCES], | computingTypeList: [...COMPUTER_RESOURCES], | ||||
cardTypeList: [...ACC_CARD_TYPE], | cardTypeList: [...ACC_CARD_TYPE], | ||||
@@ -88,7 +88,7 @@ | |||||
<script> | <script> | ||||
import BaseDialog from '~/components/BaseDialog.vue'; | import BaseDialog from '~/components/BaseDialog.vue'; | ||||
import { getResQueueCode, getResSpecificationList, addResScene, updateResScene } from '~/apis/modules/resources'; | import { getResQueueCode, getResSpecificationList, addResScene, updateResScene } from '~/apis/modules/resources'; | ||||
import { JOB_TYPE, CLUSTERS, AI_CENTER, ACC_CARD_TYPE, SPECIFICATION_STATUS } from '~/const'; | |||||
import { JOB_TYPE, CLUSTERS, ACC_CARD_TYPE, SPECIFICATION_STATUS } from '~/const'; | |||||
import { getListValueWithKey } from '~/utils'; | import { getListValueWithKey } from '~/utils'; | ||||
export default { | export default { | ||||
@@ -20,8 +20,8 @@ | |||||
<span>{{ $t('resourcesManagement.sourceSpecCode') }}</span> | <span>{{ $t('resourcesManagement.sourceSpecCode') }}</span> | ||||
</div> | </div> | ||||
<div class="content"> | <div class="content"> | ||||
<el-input v-model="dataInfo.SourceSpecId" :placeholder="$t('resourcesManagement.sourceSpecCodeTips')" maxlength="255" | |||||
:disabled="type === 'edit'"> | |||||
<el-input v-model="dataInfo.SourceSpecId" :placeholder="$t('resourcesManagement.sourceSpecCodeTips')" | |||||
maxlength="255" :disabled="type === 'edit'"> | |||||
</el-input> | </el-input> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -245,6 +245,11 @@ export default { | |||||
type: 'info', | type: 'info', | ||||
message: this.$t('resourcesManagement.onShelfCode1001') | message: this.$t('resourcesManagement.onShelfCode1001') | ||||
}); | }); | ||||
} else if (action === 'on-shelf' && res.Code === 1003) { | |||||
this.$message({ | |||||
type: 'info', | |||||
message: this.$t('resourcesManagement.onShelfCode1003') | |||||
}); | |||||
} else { | } else { | ||||
this.$message({ | this.$message({ | ||||
type: 'error', | type: 'error', | ||||
@@ -9,6 +9,9 @@ | |||||
<el-select class="select" size="medium" v-model="selStatus" @change="selectChange"> | <el-select class="select" size="medium" v-model="selStatus" @change="selectChange"> | ||||
<el-option v-for="item in statusList" :key="item.k" :label="item.v" :value="item.k" /> | <el-option v-for="item in statusList" :key="item.k" :label="item.v" :value="item.k" /> | ||||
</el-select> | </el-select> | ||||
<el-select class="select" size="medium" v-model="selAvailable" @change="selectChange"> | |||||
<el-option v-for="item in availableList" :key="item.k" :label="item.v" :value="item.k" /> | |||||
</el-select> | |||||
</div> | </div> | ||||
<div> | <div> | ||||
<el-button size="medium" icon="el-icon-refresh" @click="syncComputerNetwork" v-loading="syncLoading"> | <el-button size="medium" icon="el-icon-refresh" @click="syncComputerNetwork" v-loading="syncLoading"> | ||||
@@ -19,7 +22,7 @@ | |||||
</div> | </div> | ||||
<div class="table-container"> | <div class="table-container"> | ||||
<div style="min-height:600px;"> | <div style="min-height:600px;"> | ||||
<el-table border :data="tableData" style="width: 100%" v-loading="loading" stripe> | |||||
<el-table border :data="tableData" style="width: 100%;min-width:1700px;" v-loading="loading" stripe> | |||||
<el-table-column prop="ID" label="ID" align="center" header-align="center" width="60"></el-table-column> | <el-table-column prop="ID" label="ID" align="center" header-align="center" width="60"></el-table-column> | ||||
<el-table-column prop="SpecStr" :label="$t('resourcesManagement.resourceSpecification')" align="left" | <el-table-column prop="SpecStr" :label="$t('resourcesManagement.resourceSpecification')" align="left" | ||||
header-align="center" min-width="160"> | header-align="center" min-width="160"> | ||||
@@ -49,6 +52,14 @@ | |||||
<span style="font-weight:600;font-size:14px;">{{ scope.row.UnitPrice }}</span> | <span style="font-weight:600;font-size:14px;">{{ scope.row.UnitPrice }}</span> | ||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
<el-table-column prop="IsAvailableStr" :label="$t('resourcesManagement.resourceSpecificationIsAvailable')" align="center" | |||||
header-align="center" width="100"> | |||||
<template slot-scope="scope"> | |||||
<span :style="{ color: scope.row.IsAvailable ? 'rgb(82, 196, 26)' : 'rgb(245, 34, 45)' }">{{ | |||||
scope.row.IsAvailableStr | |||||
}}</span> | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column prop="StatusStr" :label="$t('resourcesManagement.status')" align="center" | <el-table-column prop="StatusStr" :label="$t('resourcesManagement.status')" align="center" | ||||
header-align="center" width="100"> | header-align="center" width="100"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
@@ -60,7 +71,10 @@ | |||||
<el-table-column :label="$t('operation')" align="center" header-align="center" width="100"> | <el-table-column :label="$t('operation')" align="center" header-align="center" width="100"> | ||||
<template slot-scope="scope"> | <template slot-scope="scope"> | ||||
<span v-if="scope.row.Status == '1' && !scope.row.UnitPrice"> | <span v-if="scope.row.Status == '1' && !scope.row.UnitPrice"> | ||||
<span class="op-btn" @click="showDialog('edit', scope.row)">{{ | |||||
<span v-if="scope.row.IsAvailable" class="op-btn" @click="showDialog('edit', scope.row)">{{ | |||||
$t('resourcesManagement.toSetPriceAndOnShelf') | |||||
}}</span> | |||||
<span v-else class="op-btn" style="color: rgb(187, 187, 187); cursor: not-allowed;">{{ | |||||
$t('resourcesManagement.toSetPriceAndOnShelf') | $t('resourcesManagement.toSetPriceAndOnShelf') | ||||
}}</span> | }}</span> | ||||
</span> | </span> | ||||
@@ -71,9 +85,12 @@ | |||||
}}</span> | }}</span> | ||||
</span> | </span> | ||||
<span v-if="scope.row.Status == '3' || scope.row.Status == '1' && scope.row.UnitPrice"> | <span v-if="scope.row.Status == '3' || scope.row.Status == '1' && scope.row.UnitPrice"> | ||||
<span class="op-btn" @click="onShelf(scope.row)">{{ | |||||
<span v-if="scope.row.IsAvailable" class="op-btn" @click="onShelf(scope.row)">{{ | |||||
$t('resourcesManagement.toOnShelf') | $t('resourcesManagement.toOnShelf') | ||||
}}</span> | }}</span> | ||||
<span v-else class="op-btn" style="color: rgb(187, 187, 187); cursor: not-allowed;">{{ | |||||
$t('resourcesManagement.toSetPriceAndOnShelf') | |||||
}}</span> | |||||
</span> | </span> | ||||
</template> | </template> | ||||
</el-table-column> | </el-table-column> | ||||
@@ -132,6 +149,8 @@ export default { | |||||
queueList: [{ k: '', v: this.$t('resourcesManagement.allResQueue') }], | queueList: [{ k: '', v: this.$t('resourcesManagement.allResQueue') }], | ||||
selStatus: '', | selStatus: '', | ||||
statusList: [{ k: '', v: this.$t('resourcesManagement.allStatus') }, ...SPECIFICATION_STATUS], | statusList: [{ k: '', v: this.$t('resourcesManagement.allStatus') }, ...SPECIFICATION_STATUS], | ||||
selAvailable: '', | |||||
availableList: [{ k: '', v: this.$t('resourcesManagement.resourceSpecificationIsAvailableAll') }, { k: '1', v: this.$t('resourcesManagement.available') }, { k: '2', v: this.$t('resourcesManagement.notAvailable') }], | |||||
clusterList: [...CLUSTERS], | clusterList: [...CLUSTERS], | ||||
accCardTypeList: [...ACC_CARD_TYPE], | accCardTypeList: [...ACC_CARD_TYPE], | ||||
syncLoading: false, | syncLoading: false, | ||||
@@ -178,6 +197,7 @@ export default { | |||||
const params = { | const params = { | ||||
queue: this.selQueue, | queue: this.selQueue, | ||||
status: this.selStatus, | status: this.selStatus, | ||||
available: this.selAvailable, | |||||
page: this.pageInfo.curpage, | page: this.pageInfo.curpage, | ||||
pagesize: this.pageInfo.pageSize, | pagesize: this.pageInfo.pageSize, | ||||
}; | }; | ||||
@@ -201,6 +221,8 @@ export default { | |||||
UpdatedTimeStr: formatDate(new Date(Spec.UpdatedTime * 1000), 'yyyy-MM-dd HH:mm:ss'), | UpdatedTimeStr: formatDate(new Date(Spec.UpdatedTime * 1000), 'yyyy-MM-dd HH:mm:ss'), | ||||
Status: Spec.Status.toString(), | Status: Spec.Status.toString(), | ||||
StatusStr: getListValueWithKey(this.statusList, Spec.Status.toString()), | StatusStr: getListValueWithKey(this.statusList, Spec.Status.toString()), | ||||
IsAvailable: Spec.IsAvailable, | |||||
IsAvailableStr: Spec.IsAvailable ? this.$t('resourcesManagement.available') : this.$t('resourcesManagement.notAvailable'), | |||||
} | } | ||||
}); | }); | ||||
this.tableData = data; | this.tableData = data; | ||||
@@ -280,6 +302,11 @@ export default { | |||||
type: 'info', | type: 'info', | ||||
message: this.$t('resourcesManagement.onShelfCode1001') | message: this.$t('resourcesManagement.onShelfCode1001') | ||||
}); | }); | ||||
} else if (type === 'on-shelf' && res.Code === 1003) { | |||||
this.$message({ | |||||
type: 'info', | |||||
message: this.$t('resourcesManagement.onShelfCode1003') | |||||
}); | |||||
} else { | } else { | ||||
this.$message({ | this.$message({ | ||||
type: 'error', | type: 'error', | ||||