Browse Source

Merge branch 'V20220801' into issue-zpz-0801

tags/v1.22.7.2^2
zhoupzh 3 years ago
parent
commit
817a138a93
37 changed files with 1148 additions and 264 deletions
  1. +1
    -0
      .gitignore
  2. +10
    -1
      models/cloudbrain.go
  3. +46
    -0
      modules/auth/wechat/client.go
  4. +145
    -0
      modules/auth/wechat/template.go
  5. +2
    -0
      modules/notification/base/notifier.go
  6. +4
    -0
      modules/notification/base/null.go
  7. +9
    -0
      modules/notification/notification.go
  8. +44
    -0
      modules/notification/wechat/wechat.go
  9. +7
    -1
      modules/setting/setting.go
  10. +0
    -3
      modules/storage/minio_ext.go
  11. +10
    -2
      routers/api/v1/repo/cloudbrain.go
  12. +21
    -6
      routers/api/v1/repo/modelarts.go
  13. +298
    -17
      routers/repo/cloudbrain.go
  14. +131
    -35
      routers/repo/grampus.go
  15. +18
    -0
      routers/repo/modelarts.go
  16. +1
    -1
      templates/admin/cloudbrain/list.tmpl
  17. +5
    -0
      templates/base/head.tmpl
  18. +5
    -0
      templates/base/head_course.tmpl
  19. +5
    -0
      templates/base/head_fluid.tmpl
  20. +5
    -0
      templates/base/head_home.tmpl
  21. +4
    -2
      templates/base/head_navbar.tmpl
  22. +4
    -2
      templates/base/head_navbar_fluid.tmpl
  23. +4
    -2
      templates/base/head_navbar_home.tmpl
  24. +4
    -2
      templates/base/head_navbar_pro.tmpl
  25. +5
    -0
      templates/base/head_pro.tmpl
  26. +101
    -79
      templates/repo/cloudbrain/inference/new.tmpl
  27. +3
    -1
      templates/repo/cloudbrain/show.tmpl
  28. +39
    -26
      templates/repo/cloudbrain/trainjob/new.tmpl
  29. +23
    -13
      templates/repo/grampus/trainjob/gpu/new.tmpl
  30. +55
    -5
      templates/repo/grampus/trainjob/npu/new.tmpl
  31. +84
    -54
      templates/repo/modelarts/inferencejob/new.tmpl
  32. +3
    -1
      templates/repo/modelarts/notebook/show.tmpl
  33. +33
    -5
      templates/repo/modelarts/trainjob/new.tmpl
  34. +3
    -0
      web_src/js/components/images/selectGrampusImages.vue
  35. +3
    -0
      web_src/js/components/images/selectImages.vue
  36. +9
    -6
      web_src/js/features/cloudbrainShow.js
  37. +4
    -0
      web_src/js/index.js

+ 1
- 0
.gitignore View File

@@ -55,6 +55,7 @@ coverage.all
!/custom/conf/templates
/custom/conf/app.ini
!/custom/conf/app.ini.sample
/custom/public/kanban
/data
/indexers
/log


+ 10
- 1
models/cloudbrain.go View File

@@ -206,7 +206,16 @@ func (task *Cloudbrain) CorrectCreateUnix() {

func (task *Cloudbrain) IsTerminal() bool {
status := task.Status
return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) || status == string(ModelArtsTrainJobKilled) || status == string(ModelArtsStopped) || status == string(JobStopped) || status == string(JobFailed) || status == string(JobSucceeded)
return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) ||
status == string(ModelArtsTrainJobKilled) || status == string(ModelArtsStopped) ||
status == string(JobStopped) || status == string(JobFailed) ||
status == string(JobSucceeded) || status == GrampusStatusFailed ||
status == GrampusStatusSucceeded || status == GrampusStatusStopped
}
func (task *Cloudbrain) IsRunning() bool {
status := task.Status
return status == string(ModelArtsTrainJobRunning) || status == string(ModelArtsRunning) ||
status == string(JobRunning) || status == GrampusStatusRunning
}

func ConvertDurationToStr(duration int64) string {


+ 46
- 0
modules/auth/wechat/client.go View File

@@ -19,6 +19,7 @@ const (
ACCESS_TOKEN_PATH = "/cgi-bin/token"
QR_CODE_PATH = "/cgi-bin/qrcode/create"
GET_MATERIAL_PATH = "/cgi-bin/material/batchget_material"
SEND_TEMPLATE_PATH = "/cgi-bin/message/template/send"
ACTION_QR_STR_SCENE = "QR_STR_SCENE"

ERR_CODE_ACCESSTOKEN_EXPIRE = 42001
@@ -41,12 +42,33 @@ type QRCodeRequest struct {
Action_info ActionInfo `json:"action_info"`
Expire_seconds int `json:"expire_seconds"`
}

type MaterialRequest struct {
Type string `json:"type"`
Offset int `json:"offset"`
Count int `json:"count"`
}

type TemplateMsgRequest struct {
ToUser string `json:"touser"`
TemplateId string `json:"template_id"`
Url string `json:"url"`
ClientMsgId string `json:"client_msg_id"`
Data interface{} `json:"data"`
}
type TemplateValue struct {
Value string `json:"value"`
Color string `json:"color"`
}

type CloudbrainTaskData struct {
First TemplateValue `json:"first"`
Keyword1 TemplateValue `json:"keyword1"`
Keyword2 TemplateValue `json:"keyword2"`
Keyword3 TemplateValue `json:"keyword3"`
Remark TemplateValue `json:"remark"`
}

type ActionInfo struct {
Scene Scene `json:"scene"`
}
@@ -161,3 +183,27 @@ func getErrorCodeFromResponse(r *resty.Response) int {
c, _ := strconv.Atoi(fmt.Sprint(code))
return c
}

func sendTemplateMsg(req TemplateMsgRequest) (error, bool) {
client := getWechatRestyClient()

bodyJson, _ := json.Marshal(req)
r, err := client.R().
SetHeader("Content-Type", "application/json").
SetQueryParam("access_token", GetWechatAccessToken()).
SetBody(bodyJson).
Post(setting.WechatApiHost + SEND_TEMPLATE_PATH)
if err != nil {
log.Error("sendTemplateMsg,e=%v", err)
return nil, false
}
a := r.Body()
resultMap := make(map[string]interface{}, 0)
json.Unmarshal(a, &resultMap)
errcode := resultMap["errcode"]
log.Info("sendTemplateMsg,%v", r)
if errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_EXPIRE) || errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_INVALID) {
return nil, true
}
return nil, false
}

+ 145
- 0
modules/auth/wechat/template.go View File

@@ -0,0 +1,145 @@
package wechat

import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"errors"
"fmt"
"time"
)

type JobOperateType string

const (
JobOperateTypeStart JobOperateType = "start"
JobOperateTypeStop JobOperateType = "stop"
)

func GetJobOperateTypeFromCloudbrainStatus(cloudbrain *models.Cloudbrain) JobOperateType {
if cloudbrain.IsTerminal() {
return JobOperateTypeStop
}
if cloudbrain.IsRunning() {
return JobOperateTypeStart
}
return ""
}

func SendCloudbrainStartedMsg(operateType JobOperateType, cloudbrain models.Cloudbrain) error {
defer func() {
if err := recover(); err != nil {
combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
log.Error("PANIC:", combinedErr)
}
}()
repo, err := models.GetRepositoryByID(cloudbrain.RepoID)
if err != nil {
log.Error("SendCloudbrainStartedMsg GetRepositoryByID error,%v", err)
}

if setting.CloudbrainStartedTemplateId == "" {
return nil
}

openId := models.GetUserWechatOpenId(cloudbrain.UserID)
if openId == "" {
return errors.New("Wechat openId not exist")
}
data := CloudbrainTaskData{
First: TemplateValue{Value: getCloudbrainTemplateTitle(operateType)},
Keyword1: TemplateValue{Value: cloudbrain.DisplayJobName},
Keyword2: TemplateValue{Value: getJobTypeDisplayName(cloudbrain.JobType)},
Keyword3: TemplateValue{Value: time.Unix(int64(cloudbrain.CreatedUnix), 0).Format("2006-01-02 15:04:05")},
Remark: TemplateValue{Value: getCloudbrainTemplateRemark(operateType)},
}
req := TemplateMsgRequest{
ToUser: openId,
TemplateId: setting.CloudbrainStartedTemplateId,
Url: getCloudbrainTemplateUrl(cloudbrain, repo),
ClientMsgId: string(operateType) + "_" + fmt.Sprint(cloudbrain.ID),
Data: data,
}
err, retryFlag := sendTemplateMsg(req)
if retryFlag {
log.Info("retrySendCloudbrainTemplateMsg calling")
refreshAccessToken()
err, _ = sendTemplateMsg(req)
if err != nil {
log.Error("SendCloudbrainStartedMsg err. %v", err)
return err
}
return nil
}
if err != nil {
log.Error("SendCloudbrainStartedMsg err. %v", err)
return err
}
return nil
}

func getCloudbrainTemplateUrl(cloudbrain models.Cloudbrain, repo *models.Repository) string {
url := setting.AppURL + repo.FullName()

switch cloudbrain.JobType {
case string(models.JobTypeDebug):
if cloudbrain.ComputeResource == "CPU/GPU" {
url += "/cloudbrain/" + fmt.Sprint(cloudbrain.ID)
} else {
url += "/modelarts/notebook/" + fmt.Sprint(cloudbrain.ID)
}
case string(models.JobTypeBenchmark):
url += "/cloudbrain/benchmark/" + fmt.Sprint(cloudbrain.ID)
case string(models.JobTypeTrain):
if cloudbrain.Type == models.TypeCloudBrainOne {
url += "/cloudbrain/train-job/" + fmt.Sprint(cloudbrain.JobID)
} else if cloudbrain.Type == models.TypeCloudBrainTwo {
url += "/modelarts/train-job/" + fmt.Sprint(cloudbrain.JobID)
} else if cloudbrain.Type == models.TypeC2Net {
url += "/grampus/train-job/" + fmt.Sprint(cloudbrain.JobID)
}
case string(models.JobTypeInference):
url += "/modelarts/inference-job/" + fmt.Sprint(cloudbrain.JobID)
}
return url
}

func getCloudbrainTemplateTitle(operateType JobOperateType) string {
var title string
switch operateType {
case JobOperateTypeStart:
title = "您好,您提交的算力资源申请已通过,任务已启动,请您关注运行情况。"
case JobOperateTypeStop:
title = "您好,您提交的任务已运行结束。"
}

return title

}

func getCloudbrainTemplateRemark(operateType JobOperateType) string {
var remark string
switch operateType {
case JobOperateTypeStart:
remark = "感谢您的耐心等待。"
case JobOperateTypeStop:
remark = "点击可查看运行结果"
}

return remark

}

func getJobTypeDisplayName(jobType string) string {
switch jobType {
case string(models.JobTypeDebug):
return "调试任务"
case string(models.JobTypeBenchmark):
return "评测任务"
case string(models.JobTypeTrain):
return "训练任务"
case string(models.JobTypeInference):
return "推理任务"
}
return ""
}

+ 2
- 0
modules/notification/base/notifier.go View File

@@ -56,4 +56,6 @@ type Notifier interface {
NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string)

NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType)

NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string)
}

+ 4
- 0
modules/notification/base/null.go View File

@@ -158,3 +158,7 @@ func (*NullNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Reposit
func (*NullNotifier) NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) {

}

func (*NullNotifier) NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) {

}

+ 9
- 0
modules/notification/notification.go View File

@@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/modules/notification/mail"
"code.gitea.io/gitea/modules/notification/ui"
"code.gitea.io/gitea/modules/notification/webhook"
wechatNotifier "code.gitea.io/gitea/modules/notification/wechat"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
)
@@ -35,6 +36,7 @@ func NewContext() {
RegisterNotifier(indexer.NewNotifier())
RegisterNotifier(webhook.NewNotifier())
RegisterNotifier(action.NewNotifier())
RegisterNotifier(wechatNotifier.NewNotifier())
}

// NotifyUploadAttachment notifies attachment upload message to notifiers
@@ -269,3 +271,10 @@ func NotifySyncDeleteRef(pusher *models.User, repo *models.Repository, refType,
notifier.NotifySyncDeleteRef(pusher, repo, refType, refFullName)
}
}

// NotifyChangeCloudbrainStatus
func NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) {
for _, notifier := range notifiers {
notifier.NotifyChangeCloudbrainStatus(cloudbrain, oldStatus)
}
}

+ 44
- 0
modules/notification/wechat/wechat.go View File

@@ -0,0 +1,44 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package wechat

import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth/wechat"
"code.gitea.io/gitea/modules/notification/base"
"code.gitea.io/gitea/modules/setting"
)

type wechatNotifier struct {
base.NullNotifier
}

var (
_ base.Notifier = &wechatNotifier{}
)

// NewNotifier create a new wechatNotifier notifier
func NewNotifier() base.Notifier {
return &wechatNotifier{}
}

func (*wechatNotifier) NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) {
operateType := wechat.GetJobOperateTypeFromCloudbrainStatus(cloudbrain)
if operateType == "" {
return
}
switch operateType {
case wechat.JobOperateTypeStart:
if len(setting.CloudbrainStartedNotifyList) == 0 {
return
}
for _, v := range setting.CloudbrainStartedNotifyList {
if v == cloudbrain.JobType {
go wechat.SendCloudbrainStartedMsg(operateType, *cloudbrain)
return
}
}
}
}

+ 7
- 1
modules/setting/setting.go View File

@@ -582,6 +582,10 @@ var (
TreePathOfAutoMsgReply string
TreePathOfSubscribe string

//wechat template msg config
CloudbrainStartedTemplateId string
CloudbrainStartedNotifyList []string

//nginx proxy
PROXYURL string
RadarMap = struct {
@@ -1432,7 +1436,7 @@ func NewContext() {
WechatApiHost = sec.Key("HOST").MustString("https://api.weixin.qq.com")
WechatApiTimeoutSeconds = sec.Key("TIMEOUT_SECONDS").MustInt(3)
WechatAppId = sec.Key("APP_ID").MustString("wxba77b915a305a57d")
WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198")
WechatAppSecret = sec.Key("APP_SECRET").MustString("")
WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120)
WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true)
UserNameOfWechatReply = sec.Key("AUTO_REPLY_USER_NAME").MustString("OpenIOSSG")
@@ -1440,6 +1444,8 @@ func NewContext() {
RefNameOfWechatReply = sec.Key("AUTO_REPLY_REF_NAME").MustString("master")
TreePathOfAutoMsgReply = sec.Key("AUTO_REPLY_TREE_PATH").MustString("wechat/auto_reply.json")
TreePathOfSubscribe = sec.Key("SUBSCRIBE_TREE_PATH").MustString("wechat/subscribe_reply.json")
CloudbrainStartedTemplateId = sec.Key("CLOUDBRAIN_STARTED_TEMPLATE_ID").MustString("")
CloudbrainStartedNotifyList = strings.Split(sec.Key("CLOUDBRAIN_STARTED_NOTIFY_LIST").MustString("DEBUG"), ",")

SetRadarMapConfig()



+ 0
- 3
modules/storage/minio_ext.go View File

@@ -187,9 +187,6 @@ func GetOneLevelAllObjectUnderDirMinio(bucket string, prefixRootPath string, rel
if val.Key == Prefix {
continue
}
if strings.Contains(val.Key[prefixLen:len(val.Key)-1], "/") {
continue
}
if strings.HasSuffix(val.Key, "/") {
isDir = true
fileName = val.Key[prefixLen : len(val.Key)-1]


+ 10
- 2
routers/api/v1/repo/cloudbrain.go View File

@@ -6,6 +6,7 @@
package repo

import (
"code.gitea.io/gitea/modules/notification"
"encoding/json"
"net/http"
"sort"
@@ -74,7 +75,7 @@ func GetCloudbrainTask(ctx *context.APIContext) {
log.Error("ConvertToJobResultPayload failed:", err)
return
}
oldStatus := job.Status
job.Status = result.JobStatus.State
taskRoles := result.TaskRoles
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
@@ -86,6 +87,9 @@ func GetCloudbrainTask(ctx *context.APIContext) {

if result.JobStatus.State != string(models.JobWaiting) {
models.ParseAndSetDurationFromCloudBrainOne(result, job)
if oldStatus != job.Status {
notification.NotifyChangeCloudbrainStatus(job, oldStatus)
}
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)
@@ -99,6 +103,7 @@ func GetCloudbrainTask(ctx *context.APIContext) {
"SubState": result.JobStatus.SubState,
"CreatedTime": time.Unix(result.JobStatus.CreatedTime/1000, 0).Format("2006-01-02 15:04:05"),
"CompletedTime": time.Unix(result.JobStatus.CompletedTime/1000, 0).Format("2006-01-02 15:04:05"),
"JobDuration": job.TrainJobDuration,
})

}
@@ -123,7 +128,7 @@ func GetCloudBrainInferenceJob(ctx *context.APIContext) {
log.Error("ConvertToJobResultPayload failed:", err)
return
}
oldStatus := job.Status
job.Status = result.JobStatus.State
if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) {
taskRoles := result.TaskRoles
@@ -136,6 +141,9 @@ func GetCloudBrainInferenceJob(ctx *context.APIContext) {

if result.JobStatus.State != string(models.JobWaiting) {
models.ParseAndSetDurationFromCloudBrainOne(result, job)
if oldStatus != job.Status {
notification.NotifyChangeCloudbrainStatus(job, oldStatus)
}
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)


+ 21
- 6
routers/api/v1/repo/modelarts.go View File

@@ -6,6 +6,7 @@
package repo

import (
"code.gitea.io/gitea/modules/notification"
"encoding/json"
"net/http"
"path"
@@ -42,8 +43,11 @@ func GetModelArtsNotebook(ctx *context.APIContext) {
ctx.NotFound(err)
return
}
oldStatus := job.Status
job.Status = result.Status
if oldStatus != result.Status {
notification.NotifyChangeCloudbrainStatus(job, oldStatus)
}
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)
@@ -75,21 +79,26 @@ func GetModelArtsNotebook2(ctx *context.APIContext) {
if job.StartTime == 0 && result.Lease.UpdateTime > 0 {
job.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000)
}
oldStatus := job.Status
job.Status = result.Status
if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) {
job.EndTime = timeutil.TimeStampNow()
}
job.CorrectCreateUnix()
job.ComputeAndSetDuration()
if oldStatus != result.Status {
notification.NotifyChangeCloudbrainStatus(job, oldStatus)
}
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)
}

ctx.JSON(http.StatusOK, map[string]interface{}{
"ID": ID,
"JobName": job.JobName,
"JobStatus": result.Status,
"ID": ID,
"JobName": job.JobName,
"JobStatus": result.Status,
"JobDuration": job.TrainJobDuration,
})

}
@@ -111,10 +120,13 @@ func GetModelArtsTrainJob(ctx *context.APIContext) {
ctx.NotFound(err)
return
}
oldStatus := job.Status
job.Status = modelarts.TransTrainJobStatus(result.IntStatus)
job.Duration = result.Duration
job.TrainJobDuration = result.TrainJobDuration
if oldStatus != job.Status {
notification.NotifyChangeCloudbrainStatus(job, oldStatus)
}
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)
@@ -155,7 +167,7 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) {
log.Error("ConvertToJobResultPayload failed:", err)
return
}
oldStatus := job.Status
job.Status = result.JobStatus.State
if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) {
taskRoles := result.TaskRoles
@@ -168,6 +180,9 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) {

if result.JobStatus.State != string(models.JobWaiting) {
models.ParseAndSetDurationFromCloudBrainOne(result, job)
if oldStatus != job.Status {
notification.NotifyChangeCloudbrainStatus(job, oldStatus)
}
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)


+ 298
- 17
routers/repo/cloudbrain.go View File

@@ -2,6 +2,7 @@ package repo

import (
"bufio"
"code.gitea.io/gitea/modules/notification"
"encoding/json"
"errors"
"fmt"
@@ -218,6 +219,255 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error {

return nil
}
func cloudBrainTrainJobErrorPrepare(ctx *context.Context, form auth.CreateCloudBrainForm) error {
ctx.Data["PageIsCloudBrain"] = true

if categories == nil {
json.Unmarshal([]byte(setting.BenchmarkCategory), &categories)
}
ctx.Data["benchmark_categories"] = categories.Category

ctx.Data["benchmark_types"] = GetBenchmarkTypes(ctx).BenchmarkType
queuesDetail, _ := cloudbrain.GetQueuesDetail()
if queuesDetail != nil {
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 {
org, _ := models.GetOrgByName(pool.Org)
if org != nil {
isOrgMember, _ := models.IsOrganizationMember(org.ID, 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
}

}

var Parameters modelarts.Parameters
if err := json.Unmarshal([]byte(form.Params), &Parameters); err != nil {
ctx.ServerError("json.Unmarshal failed:", err)
return err
}
ctx.Data["params"] = Parameters.Parameter
ctx.Data["boot_file"] = form.BootFile
ctx.Data["attachment"] = form.Attachment
_, datasetNames, err := models.GetDatasetInfo(form.Attachment)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
return nil
}
ctx.Data["dataset_name"] = datasetNames
ctx.Data["branch_name"] = form.BranchName
ctx.Data["datasetType"] = models.TypeCloudBrainOne

ctx.Data["display_job_name"] = form.DisplayJobName
ctx.Data["image"] = form.Image
ctx.Data["job_type"] = form.JobType
ctx.Data["gpu_type"] = form.GpuType
ctx.Data["resource_spec_id"] = form.ResourceSpecId
return nil
}

func cloudBrainInferenceJobErrorPrepare(ctx *context.Context, form auth.CreateCloudBrainInferencForm) error {
ctx.Data["PageIsCloudBrain"] = true

if categories == nil {
json.Unmarshal([]byte(setting.BenchmarkCategory), &categories)
}
ctx.Data["benchmark_categories"] = categories.Category

ctx.Data["benchmark_types"] = GetBenchmarkTypes(ctx).BenchmarkType
queuesDetail, _ := cloudbrain.GetQueuesDetail()
if queuesDetail != nil {
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 {
org, _ := models.GetOrgByName(pool.Org)
if org != nil {
isOrgMember, _ := models.IsOrganizationMember(org.ID, 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
}

}
var Parameters modelarts.Parameters
if err := json.Unmarshal([]byte(form.Params), &Parameters); err != nil {
ctx.ServerError("json.Unmarshal failed:", err)
return err
}
ctx.Data["params"] = Parameters.Parameter
ctx.Data["boot_file"] = form.BootFile
ctx.Data["attachment"] = form.Attachment
_, datasetNames, err := models.GetDatasetInfo(form.Attachment)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
return nil
}
ctx.Data["dataset_name"] = datasetNames
ctx.Data["branch_name"] = form.BranchName
ctx.Data["datasetType"] = models.TypeCloudBrainOne

ctx.Data["display_job_name"] = form.DisplayJobName
ctx.Data["image"] = form.Image
ctx.Data["job_type"] = form.JobType
ctx.Data["gpu_type"] = form.GpuType
ctx.Data["resource_spec_id"] = form.ResourceSpecId
ctx.Data["label_names"] = form.LabelName
ctx.Data["train_url"] = form.TrainUrl
ctx.Data["ckpt_name"] = form.CkptName
ctx.Data["model_name"] = form.ModelName
ctx.Data["model_version"] = form.ModelVersion
ctx.Data["description"] = form.Description
return nil
}

func CloudBrainNew(ctx *context.Context) {
err := cloudBrainNewDataPrepare(ctx)
@@ -250,28 +500,28 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
if err == nil {
if len(tasks) != 0 {
log.Error("the job name did already exist", ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr("the job name did already exist", tpl, &form)
return
}
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr("system error", tpl, &form)
return
}
}

if !jobNamePattern.MatchString(displayJobName) {
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form)
return
}

if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeTrain) {
log.Error("jobtype error:", jobType, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr("jobtype error", tpl, &form)
return
}
@@ -279,13 +529,13 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, jobType)
if err != nil {
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr("system error", tpl, &form)
return
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form)
return
}
@@ -294,7 +544,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
datasetInfos, datasetNames, err := models.GetDatasetInfo(uuids)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}
@@ -315,7 +565,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
errStr := checkCloudBrainSpecialPool(ctx, jobType, gpuQueue, resourceSpecId)

if errStr != "" {
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr(errStr, tpl, &form)
return
}
@@ -361,7 +611,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {

err = cloudbrain.GenerateTask(req)
if err != nil {
cloudBrainNewDataPrepare(ctx)
cloudBrainTrainJobErrorPrepare(ctx, form)
ctx.RenderWithErr(err.Error(), tpl, &form)
return
}
@@ -373,7 +623,6 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
}
}


func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBrainInferencForm) {
ctx.Data["PageIsCloudBrain"] = true
displayJobName := form.DisplayJobName
@@ -402,20 +651,21 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra
if err == nil {
if len(tasks) != 0 {
log.Error("the job name did already exist", ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainInferenceJobErrorPrepare(ctx, form)
ctx.RenderWithErr("the job name did already exist", tpl, &form)
return
}
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainInferenceJobErrorPrepare(ctx, form)
ctx.RenderWithErr("system error", tpl, &form)
return
}
}

if !jobNamePattern.MatchString(displayJobName) {
cloudBrainInferenceJobErrorPrepare(ctx, form)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form)
return
}
@@ -423,13 +673,13 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra
count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, jobType)
if err != nil {
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainInferenceJobErrorPrepare(ctx, form)
ctx.RenderWithErr("system error", tpl, &form)
return
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainInferenceJobErrorPrepare(ctx, form)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form)
return
}
@@ -449,7 +699,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra
datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
cloudBrainInferenceJobErrorPrepare(ctx, form)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}
@@ -486,7 +736,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra

err = cloudbrain.GenerateTask(req)
if err != nil {
cloudBrainNewDataPrepare(ctx)
cloudBrainInferenceJobErrorPrepare(ctx, form)
ctx.RenderWithErr(err.Error(), tpl, &form)
return
}
@@ -494,6 +744,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/inference-job")

}

/**
检查用户传输的参数是否符合专属资源池
*/
@@ -784,12 +1035,16 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
ctx.Data["taskRes"] = taskRes
ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics
oldStatus := task.Status
task.Status = taskRes.TaskStatuses[0].State
task.ContainerID = taskRes.TaskStatuses[0].ContainerID
task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP
models.ParseAndSetDurationFromCloudBrainOne(jobRes, task)

if task.DeletedAt.IsZero() { //normal record
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
ctx.Data["error"] = err.Error()
@@ -1143,12 +1398,15 @@ func CloudBrainStop(ctx *context.Context) {
errorMsg = "cloudbrain.Stopped_failed"
break
}
oldStatus := task.Status
task.Status = string(models.JobStopped)
if task.EndTime == 0 {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
@@ -1242,11 +1500,15 @@ func logErrorAndUpdateJobStatus(err error, taskInfo *models.Cloudbrain) {
if err != nil {
log.Warn("Failed to stop cloudBrain job:"+taskInfo.JobID, err)
} else {
oldStatus := taskInfo.Status
taskInfo.Status = string(models.JobStopped)
if taskInfo.EndTime == 0 {
taskInfo.EndTime = timeutil.TimeStampNow()
}
taskInfo.ComputeAndSetDuration()
if oldStatus != taskInfo.Status {
notification.NotifyChangeCloudbrainStatus(taskInfo, oldStatus)
}
err = models.UpdateJob(taskInfo)
if err != nil {
log.Warn("UpdateJob failed", err)
@@ -1726,9 +1988,13 @@ func SyncCloudbrainStatus() {
jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
taskRoles := jobRes.TaskRoles
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
oldStatus := task.Status
task.Status = taskRes.TaskStatuses[0].State
if task.Status != string(models.JobWaiting) {
models.ParseAndSetDurationFromCloudBrainOne(jobRes, task)
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
@@ -1755,6 +2021,9 @@ func SyncCloudbrainStatus() {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
@@ -1773,6 +2042,7 @@ func SyncCloudbrainStatus() {
}

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)
@@ -1782,6 +2052,9 @@ func SyncCloudbrainStatus() {
}
task.CorrectCreateUnix()
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
@@ -1796,6 +2069,7 @@ func SyncCloudbrainStatus() {
}

if result != nil {
oldStatus := task.Status
task.Status = modelarts.TransTrainJobStatus(result.IntStatus)
task.Duration = result.Duration / 1000
task.TrainJobDuration = result.TrainJobDuration
@@ -1808,6 +2082,9 @@ func SyncCloudbrainStatus() {
task.EndTime = task.StartTime.Add(task.Duration)
}
task.CorrectCreateUnix()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
@@ -1828,6 +2105,7 @@ func SyncCloudbrainStatus() {
if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 {
task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
}
oldStatus := task.Status
task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
task.Duration = result.JobInfo.RunSec
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration)
@@ -1839,6 +2117,9 @@ func SyncCloudbrainStatus() {
task.EndTime = task.StartTime.Add(task.Duration)
}
task.CorrectCreateUnix()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)


+ 131
- 35
routers/repo/grampus.go View File

@@ -1,15 +1,8 @@
package repo

import (
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/grampus"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"encoding/json"
"errors"
"github.com/unknwon/com"
"io/ioutil"
"net/http"
"os"
@@ -18,6 +11,15 @@ import (
"strings"
"time"

"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/grampus"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"github.com/unknwon/com"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cloudbrain"
@@ -136,6 +138,93 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err
return nil
}

func grampusTrainJobErrorPrepare(ctx *context.Context, processType string, form auth.CreateGrampusTrainJobForm) error {
ctx.Data["PageIsCloudBrain"] = true

//get valid images
images, err := grampus.GetImages(processType)
if err != nil {
log.Error("GetImages failed:", err.Error())
} else {
ctx.Data["images"] = images.Infos
}

grampus.InitSpecialPool()

ctx.Data["GPUEnabled"] = true
ctx.Data["NPUEnabled"] = true
includeCenters := make(map[string]struct{})
excludeCenters := make(map[string]struct{})
if grampus.SpecialPools != nil {
for _, pool := range grampus.SpecialPools.Pools {
if pool.IsExclusive {
if !IsUserInOrgPool(ctx.User.ID, pool) {
ctx.Data[pool.Type+"Enabled"] = false
}
} else {
if strings.Contains(strings.ToLower(processType), strings.ToLower(pool.Type)) {
if IsUserInOrgPool(ctx.User.ID, pool) {
for _, center := range pool.Pool {
includeCenters[center.Queue] = struct{}{}
}
} else {
for _, center := range pool.Pool {
excludeCenters[center.Queue] = struct{}{}
}

}

}

}
}
}

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

if processType == grampus.ProcessorTypeGPU {
ctx.Data["datasetType"] = models.TypeCloudBrainOne
} else if processType == grampus.ProcessorTypeNPU {
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
}

var Parameters modelarts.Parameters
if err := json.Unmarshal([]byte(form.Params), &Parameters); err != nil {
ctx.ServerError("json.Unmarshal failed:", err)
return err
}
ctx.Data["params"] = Parameters.Parameter
ctx.Data["boot_file"] = form.BootFile
ctx.Data["attachment"] = form.Attachment
_, datasetNames, err := models.GetDatasetInfo(form.Attachment)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
return nil
}
ctx.Data["dataset_name"] = datasetNames
ctx.Data["branch_name"] = form.BranchName
ctx.Data["image_id"] = form.ImageID

ctx.Data["display_job_name"] = form.DisplayJobName
ctx.Data["image"] = form.Image
ctx.Data["flavor"] = form.FlavorID
ctx.Data["flavor_name"] = form.FlavorName
ctx.Data["description"] = form.Description
ctx.Data["engine_name"] = form.EngineName
ctx.Data["work_server_number"] = form.WorkServerNumber

return nil
}

func getFilterSpecBySpecialPool(specs *models.GetGrampusResourceSpecsResult, includeCenters map[string]struct{}, excludeCenters map[string]struct{}) []models.GrampusSpec {
if len(includeCenters) == 0 && len(excludeCenters) == 0 {
return specs.Infos
@@ -206,14 +295,14 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
image := strings.TrimSpace(form.Image)

if !jobNamePattern.MatchString(displayJobName) {
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplGrampusTrainJobGPUNew, &form)
return
}

errStr := checkSpecialPool(ctx, "GPU")
if errStr != "" {
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr(errStr, tplGrampusTrainJobGPUNew, &form)
return
}
@@ -222,13 +311,13 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
count, err := models.GetGrampusCountByUserID(ctx.User.ID, string(models.JobTypeTrain), models.GPUResource)
if err != nil {
log.Error("GetGrampusCountByUserID failed:%v", err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("system error", tplGrampusTrainJobGPUNew, &form)
return
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -237,7 +326,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
//check param
if err := grampusParamCheckCreateTrainJob(form); err != nil {
log.Error("paramCheckCreateTrainJob failed:(%v)", err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr(err.Error(), tplGrampusTrainJobGPUNew, &form)
return
}
@@ -247,14 +336,14 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
if err == nil {
if len(tasks) != 0 {
log.Error("the job name did already exist", ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("the job name did already exist", tplGrampusTrainJobGPUNew, &form)
return
}
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("system error", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -264,7 +353,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
attachment, err := models.GetAttachmentByUUID(uuid)
if err != nil {
log.Error("GetAttachmentByUUID failed:", err.Error(), ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("dataset is not exist", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -277,7 +366,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain

if err := downloadZipCode(ctx, codeLocalPath, branchName); err != nil {
log.Error("downloadZipCode failed, server timed out: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -286,7 +375,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
//upload code
if err := uploadCodeToMinio(codeLocalPath+"/", jobName, cloudbrain.CodeMountPath+"/"); err != nil {
log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -294,7 +383,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/"
if err := mkModelPath(modelPath); err != nil {
log.Error("Failed to mkModelPath: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -302,7 +391,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
//init model readme
if err := uploadCodeToMinio(modelPath, jobName, cloudbrain.ModelMountPath+"/"); err != nil {
log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -311,7 +400,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
command, err := generateCommand(repo.Name, grampus.ProcessorTypeGPU, codeMinioPath+cloudbrain.DefaultBranchName+".zip", dataMinioPath, bootFile, params, setting.CBCodePathPrefix+jobName+cloudbrain.ModelMountPath+"/", attachment.Name)
if err != nil {
log.Error("Failed to generateCommand: %s (%v)", displayJobName, err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
return
}
@@ -343,7 +432,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
err = grampus.GenerateTrainJob(ctx, req)
if err != nil {
log.Error("GenerateTrainJob failed:%v", err.Error(), ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeGPU, form)
ctx.RenderWithErr(err.Error(), tplGrampusTrainJobGPUNew, &form)
return
}
@@ -390,14 +479,14 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
engineName := form.EngineName

if !jobNamePattern.MatchString(displayJobName) {
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplGrampusTrainJobNPUNew, &form)
return
}

errStr := checkSpecialPool(ctx, "NPU")
if errStr != "" {
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr(errStr, tplGrampusTrainJobGPUNew, &form)
return
}
@@ -406,13 +495,13 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
count, err := models.GetGrampusCountByUserID(ctx.User.ID, string(models.JobTypeTrain), models.NPUResource)
if err != nil {
log.Error("GetGrampusCountByUserID failed:%v", err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("system error", tplGrampusTrainJobNPUNew, &form)
return
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplGrampusTrainJobNPUNew, &form)
return
}
@@ -421,7 +510,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
//check param
if err := grampusParamCheckCreateTrainJob(form); err != nil {
log.Error("paramCheckCreateTrainJob failed:(%v)", err)
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr(err.Error(), tplGrampusTrainJobNPUNew, &form)
return
}
@@ -431,14 +520,14 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
if err == nil {
if len(tasks) != 0 {
log.Error("the job name did already exist", ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("the job name did already exist", tplGrampusTrainJobNPUNew, &form)
return
}
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("system error", tplGrampusTrainJobNPUNew, &form)
return
}
@@ -448,7 +537,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
attachment, err := models.GetAttachmentByUUID(uuid)
if err != nil {
log.Error("GetAttachmentByUUID failed:", err.Error(), ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("dataset is not exist", tplGrampusTrainJobNPUNew, &form)
return
}
@@ -461,7 +550,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain

if err := downloadZipCode(ctx, codeLocalPath, branchName); err != nil {
log.Error("downloadZipCode failed, server timed out: %s (%v)", repo.FullName(), err)
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("Create task failed, server timed out", tplGrampusTrainJobNPUNew, &form)
return
}
@@ -469,14 +558,14 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
//todo: upload code (send to file_server todo this work?)
if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil {
log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err)
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("Failed to obsMkdir_output", tplGrampusTrainJobNPUNew, &form)
return
}

if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("Failed to uploadCodeToObs", tplGrampusTrainJobNPUNew, &form)
return
}
@@ -485,7 +574,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
command, err := generateCommand(repo.Name, grampus.ProcessorTypeNPU, codeObsPath+cloudbrain.DefaultBranchName+".zip", dataObsPath+"'"+attachment.Name+"'", bootFile, params, setting.CodePathPrefix+jobName+modelarts.OutputPath, attachment.Name)
if err != nil {
log.Error("Failed to generateCommand: %s (%v)", displayJobName, err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobNPUNew, &form)
return
}
@@ -521,7 +610,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
err = grampus.GenerateTrainJob(ctx, req)
if err != nil {
log.Error("GenerateTrainJob failed:%v", err.Error())
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
grampusTrainJobErrorPrepare(ctx, grampus.ProcessorTypeNPU, form)
ctx.RenderWithErr(err.Error(), tplGrampusTrainJobNPUNew, &form)
return
}
@@ -550,12 +639,15 @@ func GrampusStopJob(ctx *context.Context) {
errorMsg = res.ErrorMsg
break
}
oldStatus := task.Status
task.Status = string(models.GrampusStatusStopped)
if task.EndTime == 0 {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
@@ -642,6 +734,7 @@ func GrampusTrainJobShow(ctx *context.Context) {
if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 {
task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
}
oldStatus := task.Status
task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
if task.Status != result.JobInfo.Status || result.JobInfo.Status == models.GrampusStatusRunning {
task.Duration = result.JobInfo.RunSec
@@ -654,6 +747,9 @@ func GrampusTrainJobShow(ctx *context.Context) {
task.EndTime = task.StartTime.Add(task.Duration)
}
task.CorrectCreateUnix()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob failed:" + err.Error())


+ 18
- 0
routers/repo/modelarts.go View File

@@ -272,8 +272,10 @@ func NotebookShow(ctx *context.Context) {
if result != nil {
if task.DeletedAt.IsZero() { //normal record
if task.Status != result.Status {
oldStatus := task.Status
task.Status = result.Status
models.ParseAndSetDurationFromModelArtsNotebook(result, task)
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
err = models.UpdateJob(task)
if err != nil {
log.Error("GET job error", err.Error())
@@ -510,11 +512,15 @@ func NotebookManage(ctx *context.Context) {
ID = strconv.FormatInt(newTask.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, ID, task.DisplayJobName, models.ActionCreateDebugNPUTask)
} else {
oldStatus := task.Status
task.Status = res.Status
if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
@@ -772,6 +778,12 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts
ctx.Data["config_list"] = configList.ParaConfigs
ctx.Data["bootFile"] = form.BootFile
ctx.Data["uuid"] = form.Attachment
_, datasetNames, err := models.GetDatasetInfo(form.Attachment)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
return nil
}
ctx.Data["dataset_name"] = datasetNames
ctx.Data["branch_name"] = form.BranchName
ctx.Data["datasetType"] = models.TypeCloudBrainTwo

@@ -2280,6 +2292,12 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel
ctx.Data["config_list"] = configList.ParaConfigs
ctx.Data["bootFile"] = form.BootFile
ctx.Data["uuid"] = form.Attachment
_, datasetNames, err := models.GetDatasetInfo(form.Attachment)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
return nil
}
ctx.Data["dataset_name"] = datasetNames
ctx.Data["branch_name"] = form.BranchName
ctx.Data["model_name"] = form.ModelName
ctx.Data["model_version"] = form.ModelVersion


+ 1
- 1
templates/admin/cloudbrain/list.tmpl View File

@@ -95,7 +95,7 @@
</a>
{{else if eq .JobType "INFERENCE"}}
<a class="title"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}"
title="{{.DisplayJobName}}" style="font-size: 14px;">
<span class="fitted"
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>


+ 5
- 0
templates/base/head.tmpl View File

@@ -109,6 +109,11 @@
],
{{end}}
};
{{if .IsSigned}}
window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}');
{{else}}
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">


+ 5
- 0
templates/base/head_course.tmpl View File

@@ -109,6 +109,11 @@
],
{{end}}
};
{{if .IsSigned}}
window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}');
{{else}}
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">


+ 5
- 0
templates/base/head_fluid.tmpl View File

@@ -109,6 +109,11 @@
],
{{end}}
};
{{if .IsSigned}}
window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}');
{{else}}
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">


+ 5
- 0
templates/base/head_home.tmpl View File

@@ -109,6 +109,11 @@
],
{{end}}
};
{{if .IsSigned}}
window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}');
{{else}}
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">


+ 4
- 2
templates/base/head_navbar.tmpl View File

@@ -42,7 +42,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>
@@ -73,7 +74,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>


+ 4
- 2
templates/base/head_navbar_fluid.tmpl View File

@@ -41,7 +41,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>
@@ -71,7 +72,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>


+ 4
- 2
templates/base/head_navbar_home.tmpl View File

@@ -33,7 +33,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>
@@ -64,7 +65,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>


+ 4
- 2
templates/base/head_navbar_pro.tmpl View File

@@ -43,7 +43,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>
@@ -74,7 +75,8 @@
<a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a>
{{if .IsOperator}}
<a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a>
{{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}}
<a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a>
{{end}}
<a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a>
</div>


+ 5
- 0
templates/base/head_pro.tmpl View File

@@ -109,6 +109,11 @@
],
{{end}}
};
{{if .IsSigned}}
window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}');
{{else}}
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">


+ 101
- 79
templates/repo/cloudbrain/inference/new.tmpl View File

@@ -58,18 +58,16 @@
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flaver_name" name="flaver_names" value="">
{{if $.model_version}}
<input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}">
{{else}}
<input type="hidden" id="ai_image_name" value="{{.image}}">
<input type="hidden" id="ai_model_version" name="model_version" value="">
{{end}}
{{if $.label_names}}
<input type="hidden" id="ai_model_label" name="label_names" value="{{$.label_names}}">
{{else}}
<input type="hidden" id="ai_model_label" name="label_names" value="">
{{end}}

<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="failed_model_name" value="{{$.model_name}}">
<input type="hidden" id="failed_model_version" value="{{$.model_version}}">
<input type="hidden" id="failed_ckpt_name" value="{{$.ckpt_name}}">
<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}">
<input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}">
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
@@ -102,7 +100,11 @@

<div class="unite min_title inline field">
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>

@@ -112,13 +114,8 @@
<div class="required eight wide field">
<label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<div class="ui fluid search selection dropdown loading " id="select_model">
{{if $.ckpt_name}}
<input type="hidden" name="model_name" value="{{$.model_name}}" required>
<div class="text">{{$.model_name}}</div>
{{else}}
<input type="hidden" name="model_name" required>
<div class="text"></div>
{{end}}
<i class="dropdown icon"></i>
<div class="menu" id="model_name">
</div>
@@ -126,13 +123,8 @@
</div>
<div class="three wide field">
<div class="ui fluid search selection dropdown" id="select_model_version">
{{if $.ckpt_name}}
<input type="hidden" name="train_url" value="{{$.train_url}}" required>
<div class="text">{{$.model_version}}</div>
{{else}}
<input type="hidden" name="train_url" required>
<div class="text"></div>
{{end}}
<i class="dropdown icon"></i>
<div class="menu" id="model_name_version">
</div>
@@ -141,13 +133,8 @@
</div>
<div class="five wide field">
<div class="ui fluid search selection dropdown" id="select_model_checkpoint">
{{if $.ckpt_name}}
<input type="hidden" name="ckpt_name" value="{{$.ckpt_name}}" required>
<div class="text">{{$.ckpt_name}}</div>
{{else}}
<input type="hidden" name="ckpt_name" required>
<div class="text"></div>
{{end}}
<i class="dropdown icon"></i>
<div class="menu" id="model_checkpoint">
</div>
@@ -186,8 +173,21 @@
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<select id="cloudbrain_gpu_type" class="ui search width48 dropdown gpu-type" placeholder="选择GPU类型"
style='width:385px' name="gpu_type">
{{range .inference_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{if .gpu_type}}
{{range .inference_gpu_types}}
{{if eq $.gpu_type .Queue}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .inference_gpu_types}}
{{if ne $.gpu_type .Queue}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .inference_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
</select>
</div>
@@ -196,8 +196,8 @@
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<div class="inline min_title field required">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{if .boot_file}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
{{end}}
@@ -213,22 +213,22 @@
<span id="add_run_para" style="cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span>
<input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;">
{{if ne 0 (len .params)}}
{{range $k ,$v := .params}}
<div class="two fields width85" id="para{{$k}}">
<div class="field">
<input type="text" name="shipping_first-name" value={{$v.Label}} required>
</div>
<div class="field">
<input type="text" name="shipping_last-name" value={{$v.Value}} required>
</div>
<span>
<i class="trash icon"></i>
</span>
{{if ne 0 (len .params)}}
{{range $k ,$v := .params}}
<div class="two fields width85" id="para{{$k}}">
<div class="field">
<input type="text" name="shipping_first-name" value={{$v.Label}} required>
</div>
<div class="field">
<input type="text" name="shipping_last-name" value={{$v.Value}} required>
</div>
<span>
<i class="trash icon"></i>
</span>

</div>
</div>
{{end}}
{{end}}
{{end}}
</div>
</div>

@@ -244,9 +244,22 @@
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="cloudbrain_resource_spec" class="ui search dropdown width80" placeholder="选择资源规格" name="resource_spec_id">
{{range .inference_resource_specs}}
<option name="resource_spec_id" value="{{.Id}}">
GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{if .resource_spec_id}}
{{range .inference_resource_specs}}
{{if eq $.resource_spec_id .Id}}
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
{{range .inference_resource_specs}}
{{if ne $.resource_spec_id .Id}}
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
{{else}}
{{range .inference_resource_specs}}
<option name="resource_spec_id" value="{{.Id}}">
GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
</select>
</div>
@@ -270,27 +283,35 @@
const RepoLink = {{.RepoLink}}
let nameMap,nameList
// 获取模型列表和模型名称对应的模型版本
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=0`, (data) => {
$(document).ready(function(){
modelVersion()
modelCkpt()
nameMap = data.nameMap
nameList = data.nameList
let html = ''
nameList.forEach(element => {
html += `<div class="item" data-value=${element}>${element}</div>`
});
if(nameList.length!==0){
const initModelVersion = nameMap[nameList[0]][0]
const initTrainTaskInfo = JSON.parse(initModelVersion.TrainTaskInfo)
$('#model_name').append(html)
$("#select_model").dropdown('set text',nameList[0])
$("#select_model").dropdown('set value',nameList[0],nameList[0])
}

$('#select_model').removeClass("loading")
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=0`, (data) => {
nameMap = data.nameMap
nameList = data.nameList
let faildModelName = document.getElementById('failed_model_name').value
let html = ''
nameList.forEach(element => {
html += `<div class="item" data-value=${element}>${element}</div>`
});
if(nameList.length!==0){
$('#model_name').append(html)
if(faildModelName){
$("#select_model").dropdown('set text',faildModelName)
$("#select_model").dropdown('set value',faildModelName)
}else{
$("#select_model").dropdown('set text',nameList[0])
$("#select_model").dropdown('set value',nameList[0],nameList[0])
}
}
$('#select_model').removeClass("loading")
})
})
// 根据选中的模型名称获取相应的模型版本
function modelVersion(){
let faildModelVersion = $('#failed_model_version').val()
let faildTrainUrl = $('#failed_train_url').val()
$('#select_model').dropdown({
onChange: function(value, text, $selectedItem) {
$("#select_model_version").addClass("loading")
@@ -305,13 +326,20 @@
$("#select_model_version").removeClass("loading")
const initVersionText = $('#model_name_version div.item:first-child').text()
const initVersionValue = $('#model_name_version div.item:first-child').data('value')
$("#select_model_version").dropdown('set text',initVersionText)
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
if(faildModelVersion&&faildTrainUrl){
$("#select_model_version").dropdown('set text',faildModelVersion)
$("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_version").dropdown('set text',initVersionText)
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
}
})
}
// 根据选中的模型版本获取相应的模型权重文件
function modelCkpt(){
let faildCkptName = $('#failed_ckpt_name').val()
$('#select_model_version').dropdown({
onChange: function(value, text, $selectedItem) {
const dataID = $selectedItem[0].getAttribute("data-id")
@@ -322,21 +350,23 @@
loadCheckpointList(dataID).then((res)=>{
res.forEach(element => {
const ckptSuffix = element.FileName.split(".")
const loadCheckpointFile = ['ckpt','pb','h5','json','pkl','pth','t7']
const loadCheckpointFile = ['ckpt','pb','h5','json','pkl','pth','t7','pdparams','onnx','pbtxt','keras','mlmodel','cfg','pt']
if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){
html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>`
}

})
$('#model_checkpoint').append(html)
$("#select_model_checkpoint").removeClass("loading")
const initVersionText = $('#model_checkpoint div.item:first-child').text()
const initVersionValue = $('#model_checkpoint div.item:first-child').data('value')
$("#select_model_checkpoint").dropdown('set text',initVersionText)
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
if(faildCkptName){
$("#select_model_checkpoint").dropdown('set text',faildCkptName)
$("#select_model_checkpoint").dropdown('set value',faildCkptName,faildCkptName,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_checkpoint").dropdown('set text',initVersionText)
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
})


$("input#ai_model_version").val(text)
$("input#ai_model_label").val(label)
}
@@ -397,13 +427,6 @@
msg = JSON.stringify(msg)
$('#store_run_para').val(msg)
}
function get_name(){
let name1=$("#engine_name .text").text()
let name2=$("#flaver_name .text").text()
$("input#ai_engine_name").val(name1)
$("input#ai_flaver_name").val(name2)

}
function validate(){
$('.ui.form')
.form({
@@ -475,6 +498,5 @@
validate();
$('.ui.create_train_job.green.button').click(function(e) {
send_run_para()
get_name()
})
</script>

+ 3
- 1
templates/repo/cloudbrain/show.tmpl View File

@@ -252,7 +252,9 @@
</span>
<span class="cti-mgRight-sm uc-accordionTitle-black"
id="{{.VersionName}}-duration-span">{{$.duration}}</span>
<span id="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}">
<i class="redo icon redo-color"></i>
</span>
</div>
</span>
</span>


+ 39
- 26
templates/repo/cloudbrain/trainjob/new.tmpl View File

@@ -89,8 +89,7 @@
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<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_image_name" value="{{.image}}">
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
@@ -140,11 +139,11 @@
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;"
for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255"
placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}
onchange="this.value=this.value.substring(0, 255)"
onkeydown="this.value=this.value.substring(0, 255)"
onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>

@@ -179,13 +178,25 @@
<option name="job_type" value="TRAIN">TRAIN</option>
</select>
</div>

<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<select id="cloudbrain_gpu_type" class="ui search width806 dropdown gpu-type" placeholder="选择GPU类型"
style='width:385px' name="gpu_type">
{{range .train_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{if .gpu_type}}
{{range .train_gpu_types}}
{{if eq $.gpu_type .Queue}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .train_gpu_types}}
{{if ne $.gpu_type .Queue}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .train_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
</select>
</div>
@@ -195,8 +206,8 @@

<div class="inline field min_title required">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}"
{{if .boot_file}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}"
tabindex="3" autofocus required maxlength="255">
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3"
@@ -221,7 +232,6 @@
class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span>
<input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;">
{{if .params}}
{{if ne 0 (len .params)}}
{{range $k ,$v := .params}}
<div class="two fields width85" id="para{{$k}}">
@@ -238,17 +248,28 @@
</div>
{{end}}
{{end}}
{{end}}
</div>
</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="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格"
style='width:385px' name="resource_spec_id">
{{range .train_resource_specs}}
<option name="resource_spec_id" value="{{.Id}}">
GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{if .resource_spec_id}}
{{range .train_resource_specs}}
{{if eq $.resource_spec_id .Id}}
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
{{range .train_resource_specs}}
{{if ne $.resource_spec_id .Id}}
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
{{else}}
{{range .train_resource_specs}}
<option name="resource_spec_id" value="{{.Id}}">
GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
</select>
</div>
@@ -476,16 +497,8 @@
msg = JSON.stringify(msg)
$('#store_run_para').val(msg)
}
function get_name() {
let name1 = $("#engine_name .text").text()
let name2 = $("#flaver_name .text").text()
$("input#ai_engine_name").val(name1)
$("input#ai_flaver_name").val(name2)

}
validate();
$('.ui.create_train_job.green.button').click(function (e) {
get_name()
send_run_para()
})
</script>

+ 23
- 13
templates/repo/grampus/trainjob/gpu/new.tmpl View File

@@ -80,8 +80,9 @@
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flavor_name" name="flavor_name" value="">
<input type="hidden" id="ai_image_name" value="{{.image}}">
<input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}">
<input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}">
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
@@ -123,7 +124,11 @@
<div class="min_title inline field">
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>

@@ -156,8 +161,8 @@

<div class="inline min_title field required">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{if .boot_file}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
{{end}}
@@ -199,8 +204,21 @@
<div class="required min_title inline field" id="flavor_name">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor">
{{range .flavor_infos}}
{{if .flavor}}
{{range .flavor_infos}}
{{if eq $.flavor .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{range .flavor_infos}}
{{if ne $.flavor .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{else}}
{{range .flavor_infos}}
<option name="flavor" value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
</select>
</div>
@@ -426,16 +444,8 @@
msg = JSON.stringify(msg)
$('#store_run_para').val(msg)
}
function get_name(){
let name1=$("#engine_name .text").text()
let name2=$("#flavor_name .text").text()
$("input#ai_engine_name").val(name1)
$("input#ai_flavor_name").val(name2)

}
validate();
$('.ui.create_train_job.green.button').click(function(e) {
get_name()
send_run_para()
})
</script>

+ 55
- 5
templates/repo/grampus/trainjob/npu/new.tmpl View File

@@ -77,6 +77,8 @@
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_name" value="">
<input type="hidden" id="ai_flavor_name" name="flavor_name" value="">
<input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}">
<input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}">
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
@@ -119,7 +121,11 @@

<div class="min_title inline field">
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>

@@ -150,16 +156,29 @@
<div class="required min_title inline field" id="engine_name">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label>
<select class="ui dropdown width81" id="trainjob_images" name="image_id">
{{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option>
{{if .image_id}}
{{range .images}}
{{if eq $.image_id .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{range .images}}
{{if ne $.image_id .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{else}}
{{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
</select>
</div>

<div class="inline min_title field required">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{if .boot_file}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
{{end}}
@@ -176,14 +195,45 @@
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span>
<input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;">
{{if .params}}
{{if ne 0 (len .params)}}
{{range $k ,$v := .params}}
<div class="two fields width85" id="para{{$k}}">
<div class="field">
<input type="text" name="shipping_first-name" value={{$v.Label}} required>
</div>
<div class="field">
<input type="text" name="shipping_last-name" value={{$v.Value}} required>
</div>
<span>
<i class="trash icon"></i>
</span>

</div>
{{end}}
{{end}}
{{end}}
</div>
</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 width81" id="trainjob-flavor" style='width:385px' name="flavor">
{{range .flavor_infos}}
{{if .flavor}}
{{range .flavor_infos}}
{{if eq $.flavor .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{range .flavor_infos}}
{{if ne $.flavor .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{else}}
{{range .flavor_infos}}
<option name="flavor" value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
</select>
</div>


+ 84
- 54
templates/repo/modelarts/inferencejob/new.tmpl View File

@@ -58,16 +58,16 @@
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flaver_name" name="flaver_names" value="">
{{if $.model_version}}
<input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}">
{{else}}
<input type="hidden" id="ai_model_version" name="model_version" value="">
{{end}}
{{if $.label_names}}
<input type="hidden" id="ai_model_label" name="label_names" value="{{$.label_names}}">
{{else}}
<input type="hidden" id="ai_model_label" name="label_names" value="">
{{end}}

<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="failed_model_name" value="{{$.model_name}}">
<input type="hidden" id="failed_model_version" value="{{$.model_version}}">
<input type="hidden" id="failed_ckpt_name" value="{{$.ckpt_name}}">
<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}">
<input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}">

<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
@@ -99,24 +99,22 @@
</div>

<div class="min_title inline field">
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>&nbsp;&nbsp;
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>

<!-- 模型相关配置 -->
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<div class="required unite inline min_title fields" style="width: 96.8%;">
<div class="required eight wide field">
<label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<div class="ui fluid search selection dropdown loading " id="select_model">
{{if $.ckpt_name}}
<input type="hidden" name="model_name" value="{{$.model_name}}" required>
<div class="text">{{$.model_name}}</div>
{{else}}
<input type="hidden" name="model_name" required>
<div class="text"></div>
{{end}}
<i class="dropdown icon"></i>
<div class="menu" id="model_name">
</div>
@@ -124,13 +122,8 @@
</div>
<div class="three wide field">
<div class="ui fluid search selection dropdown" id="select_model_version">
{{if $.ckpt_name}}
<input type="hidden" name="train_url" value="{{$.train_url}}" required>
<div class="text">{{$.model_version}}</div>
{{else}}
<input type="hidden" name="train_url" required>
<div class="text"></div>
{{end}}
<i class="dropdown icon"></i>
<div class="menu" id="model_name_version">
</div>
@@ -139,13 +132,8 @@
</div>
<div class="five wide field">
<div class="ui fluid search selection dropdown" id="select_model_checkpoint">
{{if $.ckpt_name}}
<input type="hidden" name="ckpt_name" value="{{$.ckpt_name}}" required>
<div class="text">{{$.ckpt_name}}</div>
{{else}}
<input type="hidden" name="ckpt_name" required>
<div class="text"></div>
{{end}}
<i class="dropdown icon"></i>
<div class="menu" id="model_checkpoint">
</div>
@@ -169,9 +157,22 @@

<div class="field" style="flex: 2;" id="engine_name">
<select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id">
{{if .engine_id}}
{{range .engine_versions}}
<option name="engine_id" value="{{.ID}}">{{.Value}}</option>
{{if eq $.engine_id .ID}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .engine_versions}}
{{if ne $.engine_id .ID}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .engine_versions}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
</select>

</div>
@@ -251,8 +252,21 @@
<div class="required min_title inline field" id="flaver_name">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select class="ui dropdown width80" id="trainjob-flavor" name="flavor">
{{range .flavor_infos}}
{{if .flavor}}
{{range .flavor_infos}}
{{if eq $.flavor .Code}}
<option value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .flavor_infos}}
{{if ne $.flavor .Code}}
<option value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .flavor_infos}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
</select>
</div>
@@ -286,30 +300,38 @@
let nameMap,nameList
$(".ui.button").attr('href',url_href)
// 获取模型列表和模型名称对应的模型版本
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=1`, (data) => {
$(document).ready(function(){
modelVersion()
modelCkpt()
nameMap = data.nameMap
nameList = data.nameList
let html = ''
nameList.forEach(element => {
html += `<div class="item" data-value=${element}>${element}</div>`
});
if(nameList.length!==0){
const initModelVersion = nameMap[nameList[0]][0]
const initTrainTaskInfo = JSON.parse(initModelVersion.TrainTaskInfo)
$('#model_name').append(html)
$("#select_model").dropdown('set text',nameList[0])
$("#select_model").dropdown('set value',nameList[0],nameList[0])
}

$('#select_model').removeClass("loading")
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=1`, (data) => {
nameMap = data.nameMap
nameList = data.nameList
let faildModelName = document.getElementById('failed_model_name').value
let html = ''
nameList.forEach(element => {
html += `<div class="item" data-value=${element}>${element}</div>`
});
if(nameList.length!==0){
$('#model_name').append(html)
if(faildModelName){
$("#select_model").dropdown('set text',faildModelName)
$("#select_model").dropdown('set value',faildModelName)
}else{
$("#select_model").dropdown('set text',nameList[0])
$("#select_model").dropdown('set value',nameList[0],nameList[0])
}
}
$('#select_model').removeClass("loading")
})
})
// 根据选中的模型名称获取相应的模型版本
function modelVersion(){
let faildModelVersion = $('#failed_model_version').val()
let faildTrainUrl = $('#failed_train_url').val()
$('#select_model').dropdown({
onChange: function(value, text, $selectedItem) {
console.log("-----------------")
$("#select_model_version").addClass("loading")
$('#model_name_version').empty()
let html = ''
@@ -322,13 +344,20 @@
$("#select_model_version").removeClass("loading")
const initVersionText = $('#model_name_version div.item:first-child').text()
const initVersionValue = $('#model_name_version div.item:first-child').data('value')
$("#select_model_version").dropdown('set text',initVersionText)
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
if(faildModelVersion&&faildTrainUrl){
$("#select_model_version").dropdown('set text',faildModelVersion)
$("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_version").dropdown('set text',initVersionText)
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
}
})
}
// 根据选中的模型版本获取相应的模型权重文件
function modelCkpt(){
let faildCkptName = $('#failed_ckpt_name').val()
$('#select_model_version').dropdown({
onChange: function(value, text, $selectedItem) {
const dataID = $selectedItem[0].getAttribute("data-id")
@@ -339,21 +368,23 @@
loadCheckpointList(dataID).then((res)=>{
res.forEach(element => {
const ckptSuffix = element.FileName.split(".")
const loadCheckpointFile = ['ckpt','pb','h5','json','pkl','pth','t7']
const loadCheckpointFile = ['ckpt','pb','h5','json','pkl','pth','t7','pdparams','onnx','pbtxt','keras','mlmodel','cfg','pt']
if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){
html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>`
}

})
$('#model_checkpoint').append(html)
$("#select_model_checkpoint").removeClass("loading")
const initVersionText = $('#model_checkpoint div.item:first-child').text()
const initVersionValue = $('#model_checkpoint div.item:first-child').data('value')
$("#select_model_checkpoint").dropdown('set text',initVersionText)
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
if(faildCkptName){
$("#select_model_checkpoint").dropdown('set text',faildCkptName)
$("#select_model_checkpoint").dropdown('set value',faildCkptName,faildCkptName,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_checkpoint").dropdown('set text',initVersionText)
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
})


$("input#ai_model_version").val(text)
$("input#ai_model_label").val(label)
}
@@ -419,7 +450,6 @@
let name2=$("#flaver_name .text").text()
$("input#ai_engine_name").val(name1)
$("input#ai_flaver_name").val(name2)

}
function validate(){
$('.ui.form')


+ 3
- 1
templates/repo/modelarts/notebook/show.tmpl View File

@@ -257,7 +257,9 @@
class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span>
<span class="cti-mgRight-sm uc-accordionTitle-black"
id="{{.VersionName}}-duration-span">{{$.duration}}</span>

<span id="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}">
<i class="redo icon redo-color"></i>
</span>
</div>
</span>
</span>


+ 33
- 5
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -128,7 +128,11 @@

<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>

@@ -170,9 +174,22 @@

<div class="field" style="flex: 2;" id="engine_name">
<select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id">
{{if .engine_id}}
{{range .engine_versions}}
<option name="engine_id" value="{{.ID}}">{{.Value}}</option>
{{if eq $.engine_id .ID}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .engine_versions}}
{{if ne $.engine_id .ID}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .engine_versions}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
</select>

</div>
@@ -220,7 +237,6 @@
</div>
</div>


<div class="required min_title field " style="display: none;">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label>
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id">
@@ -246,12 +262,24 @@
</div>
</div>
</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="trainjob-flavor" name="flavor">
{{range .flavor_infos}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{if .flavor}}
{{range .flavor_infos}}
{{if eq $.flavor .Code}}
<option value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .flavor_infos}}
{{if ne $.flavor .Code}}
<option value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .flavor_infos}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
</select>
</div>


+ 3
- 0
web_src/js/components/images/selectGrampusImages.vue View File

@@ -225,6 +225,9 @@ export default {
},
},
mounted() {
if (document.getElementById("ai_image_name")) {
this.imageAddress = document.getElementById("ai_image_name").value;
}
this.getImageListPublic();
if (
location.href.indexOf("benchmark") !== -1 ||


+ 3
- 0
web_src/js/components/images/selectImages.vue View File

@@ -498,6 +498,9 @@ export default {
},
},
mounted() {
if (document.getElementById("ai_image_name")) {
this.imageAddress = document.getElementById("ai_image_name").value;
}
this.getImageListPublic();
if (
location.href.indexOf("train-job") !== -1 ||


+ 9
- 6
web_src/js/features/cloudbrainShow.js View File

@@ -175,7 +175,9 @@ export default async function initCloudrainSow() {
let url = `/api/v1/repos${path}?version_name=${version_name}&parentDir=${parents}`;
$.get(url, (data) => {
$(`#dir_list${version_name}`).empty();
renderDir(path, data, version_name, downloadFlag, gpuFlag);
if(data.Dirs){
renderDir(path, data, version_name, downloadFlag, gpuFlag);
}
if (init === "init") {
$(`input[name=model${version_name}]`).val("");
$(`input[name=modelback${version_name}]`).val(version_name);
@@ -189,7 +191,7 @@ export default async function initCloudrainSow() {
htmlBread += "<div class='divider'> / </div>";
$(`#file_breadcrumb${version_name}`).append(htmlBread);
} else {
renderBrend(path, version_name, parents, filename, init, downloadFlag);
renderBrend(path, version_name, parents, filename, init, downloadFlag,gpuFlag);
}
}).fail(function (err) {
console.log(err, version_name);
@@ -223,7 +225,8 @@ export default async function initCloudrainSow() {
parents,
filename,
init,
downloadFlag
downloadFlag,
gpuFlag
) {
if (init == "folder") {
let htmlBrend = "";
@@ -234,11 +237,11 @@ export default async function initCloudrainSow() {
let filename1 = $(`input[name=modelback${version_name}]`).val();
if (parents1 === "") {
$(`#file_breadcrumb${version_name} .active.section`).replaceWith(
`<a class='section load-model-file' data-download-flag='${downloadFlag}' data-path='${path}' data-version='${version_name}' data-parents='${parents1}' data-filename='' data-init='init'>${sectionName}</a>`
`<a class='section load-model-file' data-download-flag='${downloadFlag}' data-gpu-flag='${gpuFlag}' data-path='${path}' data-version='${version_name}' data-parents='${parents1}' data-filename='' data-init='init'>${sectionName}</a>`
);
} else {
$(`#file_breadcrumb${version_name} .active.section`).replaceWith(
`<a class='section load-model-file' data-download-flag='${downloadFlag}' data-path='${path}' data-version='${version_name}' data-parents='${parents1}' data-filename='${filename1}'>${sectionName}</a>`
`<a class='section load-model-file' data-download-flag='${downloadFlag}' data-gpu-flag='${gpuFlag}' data-path='${path}' data-version='${version_name}' data-parents='${parents1}' data-filename='${filename1}'>${sectionName}</a>`
);
}

@@ -279,7 +282,7 @@ export default async function initCloudrainSow() {
html += "<span class='octicon octicon-file-directory'>";
html += "</span>";
if (data.Dirs[i].IsDir) {
html += `<a class='load-model-file' data-download-flag='${downloadFlag}' data-path='${path}' data-version='${version_name}' data-parents='${data.Dirs[i].ParenDir}' data-filename='${data.Dirs[i].FileName}' data-init='folder'>`;
html += `<a class='load-model-file' data-download-flag='${downloadFlag}' data-gpu-flag='${gpuFlag}' data-path='${path}' data-version='${version_name}' data-parents='${data.Dirs[i].ParenDir}' data-filename='${data.Dirs[i].FileName}' data-init='folder'>`;
html +=
"<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" +
data.Dirs[i].FileName +


+ 4
- 0
web_src/js/index.js View File

@@ -3873,6 +3873,10 @@ function initVueDataset() {
MinioUploader,
},
mounted() {
if (document.getElementById("fail_dataset_name")) {
this.dataset_name = document.getElementById("fail_dataset_name").value;
this.dataset_uuid = document.getElementById("fail_dataset_uuid").value;
}
this.getTypeList();

if (!!document.getElementById("dataset-repolink-init")) {


Loading…
Cancel
Save