Browse Source

模型管理冲突解决。

Signed-off-by: zouap <zouap@pcl.ac.cn>
tags/v1.22.7.1
zouap 3 years ago
parent
commit
dbb76aa6d6
35 changed files with 5995 additions and 3963 deletions
  1. +37
    -1
      models/attachment.go
  2. +59
    -0
      models/cloudbrain.go
  3. +116
    -14
      models/dataset.go
  4. +7
    -0
      models/dataset_star.go
  5. +184
    -141
      modules/cloudbrain/cloudbrain.go
  6. +4
    -13
      modules/modelarts/modelarts.go
  7. +2
    -0
      modules/setting/setting.go
  8. +3
    -0
      options/locale/locale_en-US.ini
  9. +3
    -2
      options/locale/locale_zh-CN.ini
  10. +4
    -3
      routers/admin/dataset.go
  11. +10
    -9
      routers/home.go
  12. +120
    -35
      routers/repo/cloudbrain.go
  13. +78
    -0
      routers/repo/dataset.go
  14. +6
    -6
      routers/repo/grampus.go
  15. +123
    -8
      routers/repo/modelarts.go
  16. +5
    -0
      routers/routes/routes.go
  17. +1
    -0
      routers/user/profile.go
  18. +2
    -2
      templates/custom/select_dataset_train.tmpl
  19. +1
    -1
      templates/explore/datasets.tmpl
  20. +1
    -1
      templates/repo/cloudbrain/benchmark/show.tmpl
  21. +5
    -5
      templates/repo/cloudbrain/new.tmpl
  22. +1
    -1
      templates/repo/cloudbrain/show.tmpl
  23. +50
    -52
      templates/repo/cloudbrain/trainjob/new.tmpl
  24. +32
    -30
      templates/repo/grampus/trainjob/gpu/new.tmpl
  25. +34
    -33
      templates/repo/grampus/trainjob/npu/new.tmpl
  26. +4
    -1
      templates/repo/modelarts/notebook/new.tmpl
  27. +32
    -44
      templates/repo/modelarts/notebook/show.tmpl
  28. +123
    -135
      templates/repo/modelarts/trainjob/new.tmpl
  29. +3
    -3
      templates/user/dashboard/feeds.tmpl
  30. +1155
    -0
      web_src/js/components/dataset/selectDataset.vue
  31. +283
    -207
      web_src/js/components/images/selectGrampusImages.vue
  32. +560
    -367
      web_src/js/components/images/selectImages.vue
  33. +2095
    -2121
      web_src/js/index.js
  34. +3
    -0
      web_src/less/_base.less
  35. +849
    -728
      web_src/less/openi.less

+ 37
- 1
models/attachment.go View File

@@ -110,8 +110,15 @@ func (a *Attachment) IncreaseDownloadCount() error {
} }


func IncreaseAttachmentUseNumber(uuid string) error { func IncreaseAttachmentUseNumber(uuid string) error {

uuidArray := strings.Split(uuid, ";")
for i := range uuidArray {
uuidArray[i] = "'" + uuidArray[i] + "'"
}

uuidInCondition := "(" + strings.Join(uuidArray, ",") + ")"
// Update use number. // Update use number.
if _, err := x.Exec("UPDATE `attachment` SET use_number=use_number+1 WHERE uuid=?", uuid); err != nil {
if _, err := x.Exec("UPDATE `attachment` SET use_number=use_number+1 WHERE uuid in " + uuidInCondition); err != nil {
return fmt.Errorf("increase attachment use count: %v", err) return fmt.Errorf("increase attachment use count: %v", err)
} }


@@ -560,6 +567,35 @@ func GetAttachmentSizeByDatasetID(datasetID int64) (int64, error) {
return total, nil return total, nil
} }


func AttachmentsByDatasetOption(datasets []int64, opts *SearchDatasetOptions) ([]*Attachment, error) {
sess := x.NewSession()
defer sess.Close()
var cond = builder.NewCond()
cond = cond.And(builder.In("attachment.dataset_id", datasets))
if opts.JustNeedZipFile {
cond = cond.And(builder.Gt{"attachment.decompress_state": 0})
}
if opts.PublicOnly {
cond = cond.And(builder.Eq{"attachment.is_private": false})
}
if opts.CloudBrainType >= 0 {
cond = cond.And(builder.Eq{"attachment.type": opts.CloudBrainType})
}
if opts.UploadAttachmentByMe {
cond = cond.And(
builder.Eq{"attachment.uploader_id": opts.User.ID},
)
}

attachments := make([]*Attachment, 0)
if err := sess.Table(&Attachment{}).Where(cond).
Find(&attachments); err != nil {
return nil, fmt.Errorf("Find: %v", err)
}
return attachments, nil

}

func GetAllAttachmentSize() (int64, error) { func GetAllAttachmentSize() (int64, error) {
return x.SumInt(&Attachment{}, "size") return x.SumInt(&Attachment{}, "size")
} }


+ 59
- 0
models/cloudbrain.go View File

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


import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
@@ -1023,6 +1024,16 @@ type Parameter struct {
type Parameters struct { type Parameters struct {
Parameter []Parameter `json:"parameter"` Parameter []Parameter `json:"parameter"`
} }
type Datasurl struct {
DatasetUrl string `json:"dataset_url"`
DatasetName string `json:"dataset_name"`
}

type DatasetDownload struct {
DatasetName string `json:"dataset_name"`
DatasetDownloadLink string `json:"dataset_download_link"`
RepositoryLink string `json:"repository_link"`
}


type DataSource struct { type DataSource struct {
DatasetID string `json:"dataset_id"` DatasetID string `json:"dataset_id"`
@@ -1979,3 +1990,51 @@ func CloudbrainAllStatic(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, er
} }
return cloudbrains, count, nil return cloudbrains, count, nil
} }

type DatasetInfo struct {
DataLocalPath string
Name string
}

func GetDatasetInfo(uuidStr string) (map[string]DatasetInfo, string, error) {
var datasetNames string
uuids := strings.Split(uuidStr, ";")
if len(uuids) > setting.MaxDatasetNum {
log.Error("the dataset count(%d) exceed the limit", len(uuids))
return nil, datasetNames, errors.New("the dataset count exceed the limit")
}

datasetInfos := make(map[string]DatasetInfo)
attachs, err := GetAttachmentsByUUIDs(uuids)
if err != nil {
log.Error("GetAttachmentsByUUIDs failed: %v", err)
return nil, datasetNames, err
}
for i, attach := range attachs {
fileName := strings.TrimSuffix(strings.TrimSuffix(strings.TrimSuffix(attach.Name, ".zip"), ".tar.gz"), ".tgz")
for _, datasetInfo := range datasetInfos {
if fileName == datasetInfo.Name {
log.Error("the dataset name is same: %v", attach.Name)
return nil, datasetNames, errors.New("the dataset name is same")
}
}

dataLocalPath := setting.Attachment.Minio.RealPath +
setting.Attachment.Minio.Bucket + "/" +
setting.Attachment.Minio.BasePath +
AttachmentRelativePath(attach.UUID) +
attach.UUID

datasetInfos[attach.UUID] = DatasetInfo{
DataLocalPath: dataLocalPath,
Name: fileName,
}
if i == 0 {
datasetNames = attach.Name
} else {
datasetNames += ";" + attach.Name
}
}

return datasetInfos, datasetNames, nil
}

+ 116
- 14
models/dataset.go View File

@@ -81,12 +81,14 @@ func (datasets DatasetList) loadAttributes(e Engine) error {
if err := e. if err := e.
Where("id > 0"). Where("id > 0").
In("id", keysInt64(userIdSet)). In("id", keysInt64(userIdSet)).
Cols("id", "lower_name", "name", "full_name", "email").
Find(&users); err != nil { Find(&users); err != nil {
return fmt.Errorf("find users: %v", err) return fmt.Errorf("find users: %v", err)
} }
if err := e. if err := e.
Where("id > 0"). Where("id > 0").
In("id", keysInt64(set)). In("id", keysInt64(set)).
Cols("id", "owner_id", "owner_name", "lower_name", "name", "description", "alias", "lower_alias","is_private").
Find(&repos); err != nil { Find(&repos); err != nil {
return fmt.Errorf("find repos: %v", err) return fmt.Errorf("find repos: %v", err)
} }
@@ -98,19 +100,81 @@ func (datasets DatasetList) loadAttributes(e Engine) error {
return nil return nil
} }


func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions) error {
if len(datasets) == 0 {
return nil
}
datasetIDs := make([]int64, len(datasets))
for i := range datasets {
datasetIDs[i] = datasets[i].ID
}
attachments, err := AttachmentsByDatasetOption(datasetIDs, opts)
if err != nil {
return fmt.Errorf("GetAttachmentsByDatasetIds failed error: %v", err)
}

permissionMap := make(map[int64]*Permission, len(datasets))

for _, attachment := range attachments {

for i := range datasets {
if attachment.DatasetID == datasets[i].ID {
if opts.StarByMe {
var permission *Permission
if permission = permissionMap[datasets[i].ID]; permission == nil {
permissionInstance, err := GetUserRepoPermission(datasets[i].Repo, opts.User)
if err != nil {
return fmt.Errorf("GetPermission failed error: %v", err)
}
permission = &permissionInstance
permissionMap[datasets[i].ID]=&permissionInstance
}

if permission.HasAccess() {
datasets[i].Attachments = append(datasets[i].Attachments, attachment)
} else if !attachment.IsPrivate {
datasets[i].Attachments = append(datasets[i].Attachments, attachment)
}
} else {
datasets[i].Attachments = append(datasets[i].Attachments, attachment)
}

}

}

}

for i := range datasets {
if datasets[i].Attachments==nil{
datasets[i].Attachments=[]*Attachment{}
}
datasets[i].Repo.Owner = nil
}
return nil

}

type SearchDatasetOptions struct { type SearchDatasetOptions struct {
Keyword string Keyword string
OwnerID int64 OwnerID int64
User *User
RepoID int64 RepoID int64
IncludePublic bool IncludePublic bool
RecommendOnly bool RecommendOnly bool
Category string Category string
Task string Task string
License string License string
DatasetIDs []int64
DatasetIDs []int64 // 目前只在StarByMe为true时起作用
ListOptions ListOptions
SearchOrderBy SearchOrderBy
IsOwner bool
IsOwner bool
StarByMe bool
CloudBrainType int //0 cloudbrain 1 modelarts -1 all
PublicOnly bool
JustNeedZipFile bool
NeedAttachment bool
UploadAttachmentByMe bool
} }


func CreateDataset(dataset *Dataset) (err error) { func CreateDataset(dataset *Dataset) (err error) {
@@ -159,30 +223,40 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond {
if opts.RepoID > 0 { if opts.RepoID > 0 {
cond = cond.And(builder.Eq{"dataset.repo_id": opts.RepoID}) cond = cond.And(builder.Eq{"dataset.repo_id": opts.RepoID})
} }
if opts.IncludePublic {

if opts.PublicOnly {
cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic})
cond = cond.And(builder.Eq{"attachment.is_private": false})
} else if opts.IncludePublic {
cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic})
cond = cond.And(builder.Eq{"attachment.is_private": false}) cond = cond.And(builder.Eq{"attachment.is_private": false})
if opts.OwnerID > 0 { if opts.OwnerID > 0 {

subCon := builder.NewCond() subCon := builder.NewCond()
subCon = subCon.And(builder.Eq{"repository.owner_id": opts.OwnerID}) subCon = subCon.And(builder.Eq{"repository.owner_id": opts.OwnerID})
subCon = generateFilterCond(opts, subCon) subCon = generateFilterCond(opts, subCon)
cond = cond.Or(subCon) cond = cond.Or(subCon)


} }
} else if opts.OwnerID > 0 {
} else if opts.OwnerID > 0 && !opts.StarByMe && !opts.UploadAttachmentByMe {
cond = cond.And(builder.Eq{"repository.owner_id": opts.OwnerID}) cond = cond.And(builder.Eq{"repository.owner_id": opts.OwnerID})
if !opts.IsOwner { if !opts.IsOwner {
cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic})
cond = cond.And(builder.Eq{"attachment.is_private": false}) cond = cond.And(builder.Eq{"attachment.is_private": false})
} }
} }

if len(opts.DatasetIDs) > 0 { if len(opts.DatasetIDs) > 0 {
subCon := builder.NewCond()
subCon = subCon.And(builder.In("dataset.id", opts.DatasetIDs))
subCon = generateFilterCond(opts, subCon)
cond = cond.Or(subCon)
if opts.StarByMe {
cond = cond.And(builder.In("dataset.id", opts.DatasetIDs))
} else {
subCon := builder.NewCond()
subCon = subCon.And(builder.In("dataset.id", opts.DatasetIDs))
subCon = generateFilterCond(opts, subCon)
cond = cond.Or(subCon)
}
} else {
if opts.StarByMe {
cond = cond.And(builder.Eq{"dataset.id": -1})
}
} }


return cond return cond
@@ -208,6 +282,17 @@ func generateFilterCond(opts *SearchDatasetOptions, cond builder.Cond) builder.C
cond = cond.And(builder.Eq{"dataset.recommend": opts.RecommendOnly}) cond = cond.And(builder.Eq{"dataset.recommend": opts.RecommendOnly})
} }


if opts.JustNeedZipFile {
cond = cond.And(builder.Gt{"attachment.decompress_state": 0})
}

if opts.CloudBrainType >= 0 {
cond = cond.And(builder.Eq{"attachment.type": opts.CloudBrainType})
}
if opts.UploadAttachmentByMe {
cond = cond.And(builder.Eq{"attachment.uploader_id": opts.User.ID})
}

return cond return cond
} }


@@ -234,7 +319,6 @@ func SearchDatasetByCondition(opts *SearchDatasetOptions, cond builder.Cond) (Da
sess.Select(selectColumnsSql).Join("INNER", "repository", "repository.id = dataset.repo_id"). sess.Select(selectColumnsSql).Join("INNER", "repository", "repository.id = dataset.repo_id").
Join("INNER", "attachment", "attachment.dataset_id=dataset.id"). Join("INNER", "attachment", "attachment.dataset_id=dataset.id").
Where(cond).OrderBy(opts.SearchOrderBy.String()) Where(cond).OrderBy(opts.SearchOrderBy.String())

if opts.PageSize > 0 { if opts.PageSize > 0 {
sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
} }
@@ -246,6 +330,12 @@ func SearchDatasetByCondition(opts *SearchDatasetOptions, cond builder.Cond) (Da
return nil, 0, fmt.Errorf("LoadAttributes: %v", err) return nil, 0, fmt.Errorf("LoadAttributes: %v", err)
} }


if opts.NeedAttachment {
if err = datasets.loadAttachmentAttributes(opts); err != nil {
return nil, 0, fmt.Errorf("LoadAttributes: %v", err)
}
}

return datasets, count, nil return datasets, count, nil
} }


@@ -362,10 +452,22 @@ func UpdateDataset(ctx DBContext, rel *Dataset) error {
func IncreaseDatasetUseCount(uuid string) { func IncreaseDatasetUseCount(uuid string) {


IncreaseAttachmentUseNumber(uuid) IncreaseAttachmentUseNumber(uuid)
attachments, _ := GetAttachmentsByUUIDs(strings.Split(uuid, ";"))

countMap := make(map[int64]int)

for _, attachment := range attachments {
value, ok := countMap[attachment.DatasetID]
if ok {
countMap[attachment.DatasetID] = value + 1
} else {
countMap[attachment.DatasetID] = 1
}

}


attachment, _ := GetAttachmentByUUID(uuid)
if attachment != nil {
x.Exec("UPDATE `dataset` SET use_count=use_count+1 WHERE id=?", attachment.DatasetID)
for key, value := range countMap {
x.Exec("UPDATE `dataset` SET use_count=use_count+? WHERE id=?", value, key)
} }


} }


+ 7
- 0
models/dataset_star.go View File

@@ -68,3 +68,10 @@ func isDatasetStaring(e Engine, userID, datasetID int64) bool {
has, _ := e.Get(&DatasetStar{0, userID, datasetID, 0}) has, _ := e.Get(&DatasetStar{0, userID, datasetID, 0})
return has return has
} }

func GetDatasetIdsStarByUser(userID int64) []int64 {
var datasets []int64
_ = x.Table("dataset_star").Where("uid=?", userID).
Cols("dataset_star.dataset_id").Find(&datasets)
return datasets
}

+ 184
- 141
modules/cloudbrain/cloudbrain.go View File

@@ -44,6 +44,32 @@ var (
TrainResourceSpecs *models.ResourceSpecs TrainResourceSpecs *models.ResourceSpecs
) )


type GenerateCloudBrainTaskReq struct {
Ctx *context.Context
DisplayJobName string
JobName string
Image string
Command string
CodePath string
ModelPath string
BenchmarkPath string
Snn4ImageNetPath string
BrainScorePath string
JobType string
GpuQueue string
Description string
BranchName string
BootFile string
Params string
CommitID string
Uuids string
DatasetNames string
DatasetInfos map[string]models.DatasetInfo
BenchmarkTypeID int
BenchmarkChildTypeID int
ResourceSpecId int
}

func isAdminOrOwnerOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error) bool { func isAdminOrOwnerOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error) bool {
if !ctx.IsSigned { if !ctx.IsSigned {
return false return false
@@ -184,23 +210,17 @@ func AdminOrImageCreaterRight(ctx *context.Context) {


} }


func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description, branchName, bootFile, params, commitID string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error {

dataActualPath := setting.Attachment.Minio.RealPath +
setting.Attachment.Minio.Bucket + "/" +
setting.Attachment.Minio.BasePath +
models.AttachmentRelativePath(uuid) +
uuid

func GenerateTask(req GenerateCloudBrainTaskReq) error {
var resourceSpec *models.ResourceSpec var resourceSpec *models.ResourceSpec
var versionCount int var versionCount int
if jobType == string(models.JobTypeTrain) {

if req.JobType == string(models.JobTypeTrain) {
versionCount = 1 versionCount = 1
if TrainResourceSpecs == nil { if TrainResourceSpecs == nil {
json.Unmarshal([]byte(setting.TrainResourceSpecs), &TrainResourceSpecs) json.Unmarshal([]byte(setting.TrainResourceSpecs), &TrainResourceSpecs)
} }
for _, spec := range TrainResourceSpecs.ResourceSpec { for _, spec := range TrainResourceSpecs.ResourceSpec {
if resourceSpecId == spec.Id {
if req.ResourceSpecId == spec.Id {
resourceSpec = spec resourceSpec = spec
} }
} }
@@ -209,7 +229,7 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command,
json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs)
} }
for _, spec := range ResourceSpecs.ResourceSpec { for _, spec := range ResourceSpecs.ResourceSpec {
if resourceSpecId == spec.Id {
if req.ResourceSpecId == spec.Id {
resourceSpec = spec resourceSpec = spec
} }
} }
@@ -217,25 +237,74 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command,
} }


if resourceSpec == nil { if resourceSpec == nil {
log.Error("no such resourceSpecId(%d)", resourceSpecId, ctx.Data["MsgID"])
log.Error("no such resourceSpecId(%d)", req.ResourceSpecId, req.Ctx.Data["MsgID"])
return errors.New("no such resourceSpec") return errors.New("no such resourceSpec")
} }


var datasetName string
attach, err := models.GetAttachmentByUUID(uuid)
if err != nil {
//for benchmark, do not return error
log.Error("GetAttachmentByUUID failed:%v", err)
volumes := []models.Volume{
{
HostPath: models.StHostPath{
Path: req.CodePath,
MountPath: CodeMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: req.ModelPath,
MountPath: ModelMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: req.BenchmarkPath,
MountPath: BenchMarkMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: req.Snn4ImageNetPath,
MountPath: Snn4imagenetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: req.BrainScorePath,
MountPath: BrainScoreMountPath,
ReadOnly: true,
},
},
}

if len(req.DatasetInfos) == 1 {
volumes = append(volumes, models.Volume{
HostPath: models.StHostPath{
Path: req.DatasetInfos[req.Uuids].DataLocalPath,
MountPath: DataSetMountPath,
ReadOnly: true,
},
})
} else { } else {
datasetName = attach.Name
for _, dataset := range req.DatasetInfos {
volumes = append(volumes, models.Volume{
HostPath: models.StHostPath{
Path: dataset.DataLocalPath,
MountPath: DataSetMountPath + "/" + dataset.Name,
ReadOnly: true,
},
})
}
} }


createTime := timeutil.TimeStampNow() createTime := timeutil.TimeStampNow()
jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName,
jobResult, err := CreateJob(req.JobName, models.CreateJobParams{
JobName: req.JobName,
RetryCount: 1, RetryCount: 1,
GpuType: gpuQueue,
Image: image,
GpuType: req.GpuQueue,
Image: req.Image,
TaskRoles: []models.TaskRole{ TaskRoles: []models.TaskRole{
{ {
Name: SubTaskName, Name: SubTaskName,
@@ -246,94 +315,51 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command,
GPUNumber: resourceSpec.GpuNum, GPUNumber: resourceSpec.GpuNum,
MemoryMB: resourceSpec.MemMiB, MemoryMB: resourceSpec.MemMiB,
ShmMB: resourceSpec.ShareMemMiB, ShmMB: resourceSpec.ShareMemMiB,
Command: command,
Command: req.Command,
NeedIBDevice: false, NeedIBDevice: false,
IsMainRole: false, IsMainRole: false,
UseNNI: false, UseNNI: false,
}, },
}, },
Volumes: []models.Volume{
{
HostPath: models.StHostPath{
Path: codePath,
MountPath: CodeMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: dataActualPath,
MountPath: DataSetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: modelPath,
MountPath: ModelMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: benchmarkPath,
MountPath: BenchMarkMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: snn4imagenetPath,
MountPath: Snn4imagenetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: brainScorePath,
MountPath: BrainScoreMountPath,
ReadOnly: true,
},
},
},
Volumes: volumes,
}) })
if err != nil { if err != nil {
log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
log.Error("CreateJob failed:", err.Error(), req.Ctx.Data["MsgID"])
return err return err
} }
if jobResult.Code != Success { if jobResult.Code != Success {
log.Error("CreateJob(%s) failed:%s", jobName, jobResult.Msg, ctx.Data["MsgID"])
log.Error("CreateJob(%s) failed:%s", req.JobName, jobResult.Msg, req.Ctx.Data["MsgID"])
return errors.New(jobResult.Msg) return errors.New(jobResult.Msg)
} }


var jobID = jobResult.Payload["jobId"].(string) var jobID = jobResult.Payload["jobId"].(string)
err = models.CreateCloudbrain(&models.Cloudbrain{ err = models.CreateCloudbrain(&models.Cloudbrain{
Status: string(models.JobWaiting), Status: string(models.JobWaiting),
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
UserID: req.Ctx.User.ID,
RepoID: req.Ctx.Repo.Repository.ID,
JobID: jobID, JobID: jobID,
JobName: jobName,
DisplayJobName: displayJobName,
JobName: req.JobName,
DisplayJobName: req.DisplayJobName,
SubTaskName: SubTaskName, SubTaskName: SubTaskName,
JobType: jobType,
JobType: req.JobType,
Type: models.TypeCloudBrainOne, Type: models.TypeCloudBrainOne,
Uuid: uuid,
Image: image,
GpuQueue: gpuQueue,
ResourceSpecId: resourceSpecId,
Uuid: req.Uuids,
Image: req.Image,
GpuQueue: req.GpuQueue,
ResourceSpecId: req.ResourceSpecId,
ComputeResource: models.GPUResource, ComputeResource: models.GPUResource,
BenchmarkTypeID: benchmarkTypeID,
BenchmarkChildTypeID: benchmarkChildTypeID,
Description: description,
BenchmarkTypeID: req.BenchmarkTypeID,
BenchmarkChildTypeID: req.BenchmarkChildTypeID,
Description: req.Description,
IsLatestVersion: "1", IsLatestVersion: "1",
VersionCount: versionCount, VersionCount: versionCount,
BranchName: branchName,
BootFile: bootFile,
DatasetName: datasetName,
Parameters: params,
BranchName: req.BranchName,
BootFile: req.BootFile,
DatasetName: req.DatasetNames,
Parameters: req.Params,
CreatedUnix: createTime, CreatedUnix: createTime,
UpdatedUnix: createTime, UpdatedUnix: createTime,
CommitID: commitID,
CommitID: req.CommitID,
}) })


if err != nil { if err != nil {
@@ -342,17 +368,17 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command,


task, err := models.GetCloudbrainByJobID(jobID) task, err := models.GetCloudbrainByJobID(jobID)
if err != nil { if err != nil {
log.Error("GetCloudbrainByName failed: %v", err.Error())
log.Error("GetCloudbrainByJobID failed: %v", err.Error())
return err return err
} }
stringId := strconv.FormatInt(task.ID, 10) stringId := strconv.FormatInt(task.ID, 10)


if IsBenchmarkJob(jobType) {
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask)
} else if string(models.JobTypeTrain) == jobType {
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, displayJobName, models.ActionCreateGPUTrainTask)
if IsBenchmarkJob(req.JobType) {
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, stringId, req.DisplayJobName, models.ActionCreateBenchMarkTask)
} else if string(models.JobTypeTrain) == req.JobType {
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateGPUTrainTask)
} else { } else {
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugGPUTask)
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, stringId, req.DisplayJobName, models.ActionCreateDebugGPUTask)
} }


return nil return nil
@@ -363,11 +389,6 @@ func IsBenchmarkJob(jobType string) bool {
} }


func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error { func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error {
dataActualPath := setting.Attachment.Minio.RealPath +
setting.Attachment.Minio.Bucket + "/" +
setting.Attachment.Minio.BasePath +
models.AttachmentRelativePath(task.Uuid) +
task.Uuid
jobName := task.JobName jobName := task.JobName


var resourceSpec *models.ResourceSpec var resourceSpec *models.ResourceSpec
@@ -385,6 +406,70 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e
return errors.New("no such resourceSpec") return errors.New("no such resourceSpec")
} }


datasetInfos, _, err := models.GetDatasetInfo(task.Uuid)
if err != nil {
log.Error("GetDatasetInfo failed:%v", err, ctx.Data["MsgID"])
return err
}

volumes := []models.Volume{
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, CodeMountPath+"/"),
MountPath: CodeMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, ModelMountPath+"/"),
MountPath: ModelMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, BenchMarkMountPath+"/"),
MountPath: BenchMarkMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, Snn4imagenetMountPath+"/"),
MountPath: Snn4imagenetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, BrainScoreMountPath+"/"),
MountPath: BrainScoreMountPath,
ReadOnly: true,
},
},
}

if len(datasetInfos) == 1 {
volumes = append(volumes, models.Volume{
HostPath: models.StHostPath{
Path: datasetInfos[task.Uuid].DataLocalPath,
MountPath: DataSetMountPath,
ReadOnly: true,
},
})
} else {
for _, dataset := range datasetInfos {
volumes = append(volumes, models.Volume{
HostPath: models.StHostPath{
Path: dataset.DataLocalPath,
MountPath: DataSetMountPath + "/" + dataset.Name,
ReadOnly: true,
},
})
}
}

createTime := timeutil.TimeStampNow() createTime := timeutil.TimeStampNow()
jobResult, err := CreateJob(jobName, models.CreateJobParams{ jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName, JobName: jobName,
@@ -407,50 +492,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e
UseNNI: false, UseNNI: false,
}, },
}, },
Volumes: []models.Volume{
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, CodeMountPath+"/"),
MountPath: CodeMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: dataActualPath,
MountPath: DataSetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, ModelMountPath+"/"),
MountPath: ModelMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, BenchMarkMountPath+"/"),
MountPath: BenchMarkMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, Snn4imagenetMountPath+"/"),
MountPath: Snn4imagenetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, BrainScoreMountPath+"/"),
MountPath: BrainScoreMountPath,
ReadOnly: true,
},
},
},
Volumes: volumes,
}) })
if err != nil { if err != nil {
log.Error("CreateJob failed:%v", err.Error(), ctx.Data["MsgID"]) log.Error("CreateJob failed:%v", err.Error(), ctx.Data["MsgID"])
@@ -473,6 +515,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e
JobType: task.JobType, JobType: task.JobType,
Type: task.Type, Type: task.Type,
Uuid: task.Uuid, Uuid: task.Uuid,
DatasetName: task.DatasetName,
Image: task.Image, Image: task.Image,
GpuQueue: task.GpuQueue, GpuQueue: task.GpuQueue,
ResourceSpecId: task.ResourceSpecId, ResourceSpecId: task.ResourceSpecId,


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

@@ -51,6 +51,7 @@ const (
Lines = 500 Lines = 500
TrainUrl = "train_url" TrainUrl = "train_url"
DataUrl = "data_url" DataUrl = "data_url"
MultiDataUrl = "multi_data_url"
ResultUrl = "result_url" ResultUrl = "result_url"
CkptUrl = "ckpt_url" CkptUrl = "ckpt_url"
DeviceTarget = "device_target" DeviceTarget = "device_target"
@@ -99,6 +100,7 @@ type GenerateTrainJobReq struct {
TotalVersionCount int TotalVersionCount int
UserImageUrl string UserImageUrl string
UserCommand string UserCommand string
DatasetName string
} }


type GenerateInferenceJobReq struct { type GenerateInferenceJobReq struct {
@@ -338,11 +340,6 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
return err return err
} }


attach, err := models.GetAttachmentByUUID(req.Uuid)
if err != nil {
log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error())
return err
}
jobId := strconv.FormatInt(jobResult.JobID, 10) jobId := strconv.FormatInt(jobResult.JobID, 10)
err = models.CreateCloudbrain(&models.Cloudbrain{ err = models.CreateCloudbrain(&models.Cloudbrain{
Status: TransTrainJobStatus(jobResult.Status), Status: TransTrainJobStatus(jobResult.Status),
@@ -356,7 +353,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
VersionID: jobResult.VersionID, VersionID: jobResult.VersionID,
VersionName: jobResult.VersionName, VersionName: jobResult.VersionName,
Uuid: req.Uuid, Uuid: req.Uuid,
DatasetName: attach.Name,
DatasetName: req.DatasetName,
CommitID: req.CommitID, CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion, IsLatestVersion: req.IsLatestVersion,
ComputeResource: models.NPUResource, ComputeResource: models.NPUResource,
@@ -435,12 +432,6 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job
return err return err
} }


attach, err := models.GetAttachmentByUUID(req.Uuid)
if err != nil {
log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error())
return err
}

var jobTypes []string var jobTypes []string
jobTypes = append(jobTypes, string(models.JobTypeTrain)) jobTypes = append(jobTypes, string(models.JobTypeTrain))
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
@@ -468,7 +459,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job
VersionID: jobResult.VersionID, VersionID: jobResult.VersionID,
VersionName: jobResult.VersionName, VersionName: jobResult.VersionName,
Uuid: req.Uuid, Uuid: req.Uuid,
DatasetName: attach.Name,
DatasetName: req.DatasetName,
CommitID: req.CommitID, CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion, IsLatestVersion: req.IsLatestVersion,
PreVersionName: req.PreVersionName, PreVersionName: req.PreVersionName,


+ 2
- 0
modules/setting/setting.go View File

@@ -466,6 +466,7 @@ var (
TrainGpuTypes string TrainGpuTypes string
TrainResourceSpecs string TrainResourceSpecs string
MaxModelSize float64 MaxModelSize float64
MaxDatasetNum int


//benchmark config //benchmark config
IsBenchmarkEnabled bool IsBenchmarkEnabled bool
@@ -1312,6 +1313,7 @@ func NewContext() {
TrainGpuTypes = sec.Key("TRAIN_GPU_TYPES").MustString("") TrainGpuTypes = sec.Key("TRAIN_GPU_TYPES").MustString("")
TrainResourceSpecs = sec.Key("TRAIN_RESOURCE_SPECS").MustString("") TrainResourceSpecs = sec.Key("TRAIN_RESOURCE_SPECS").MustString("")
MaxModelSize = sec.Key("MAX_MODEL_SIZE").MustFloat64(500) MaxModelSize = sec.Key("MAX_MODEL_SIZE").MustFloat64(500)
MaxDatasetNum = sec.Key("MAX_DATASET_NUM").MustInt(5)


sec = Cfg.Section("benchmark") sec = Cfg.Section("benchmark")
IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false)


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

@@ -902,6 +902,7 @@ unzip_successed=Unzip Successed
unzip_failed=Unzip Failed unzip_failed=Unzip Failed
unzip_stared=Unzipping unzip_stared=Unzipping
unzip_status=Unzip Status unzip_status=Unzip Status
collection_num=Collection Nums
[repo] [repo]
owner = Owner owner = Owner
repo_name = Repository Name repo_name = Repository Name
@@ -3081,3 +3082,5 @@ TRAIN = TRAIN
INFERENCE = INFERENCE INFERENCE = INFERENCE
BENCHMARK = BENCHMARK BENCHMARK = BENCHMARK
brain_area = Brain Area brain_area = Brain Area

error.dataset_select = dataset select error:the count exceed the limit or has same name

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

@@ -907,7 +907,7 @@ unzip_successed=解压成功
unzip_failed=解压失败 unzip_failed=解压失败
unzip_stared=解压中 unzip_stared=解压中
unzip_status=解压状态 unzip_status=解压状态
collection_num=收藏数量
[repo] [repo]
owner=拥有者 owner=拥有者
repo_name=项目名称 repo_name=项目名称
@@ -1477,7 +1477,7 @@ issues.filter_sort.mostforks=派生由多到少
issues.filter_sort.fewestforks=派生由少到多 issues.filter_sort.fewestforks=派生由少到多
issues.filter_sort.downloadtimes=下载次数 issues.filter_sort.downloadtimes=下载次数
issues.filter_sort.citations=引用次数 issues.filter_sort.citations=引用次数
issues.filter_sort.moststars=收藏数量
issues.filter_sort.moststars=点赞由多到少
issues.filter_sort.mostusecount=最多引用 issues.filter_sort.mostusecount=最多引用
issues.filter_sort.fewestusecount=最少引用 issues.filter_sort.fewestusecount=最少引用


@@ -3098,3 +3098,4 @@ INFERENCE = 推理任务
BENCHMARK = 评测任务 BENCHMARK = 评测任务
brain_area = 脑区 brain_area = 脑区


error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集

+ 4
- 3
routers/admin/dataset.go View File

@@ -77,9 +77,10 @@ func Datasets(ctx *context.Context) {
Page: page, Page: page,
PageSize: setting.UI.ExplorePagingNum, PageSize: setting.UI.ExplorePagingNum,
}, },
Keyword: keyword,
RecommendOnly: ctx.QueryBool("recommend"),
SearchOrderBy: orderBy,
Keyword: keyword,
RecommendOnly: ctx.QueryBool("recommend"),
CloudBrainType: -1,
SearchOrderBy: orderBy,
}) })
if err != nil { if err != nil {
ctx.ServerError("SearchDataset", err) ctx.ServerError("SearchDataset", err)


+ 10
- 9
routers/home.go View File

@@ -351,15 +351,16 @@ func ExploreDatasets(ctx *context.Context) {
} }


opts := &models.SearchDatasetOptions{ opts := &models.SearchDatasetOptions{
Keyword: keyword,
IncludePublic: true,
SearchOrderBy: orderBy,
Category: category,
Task: task,
License: license,
OwnerID: ownerID,
DatasetIDs: datasetsIds,
RecommendOnly: ctx.QueryBool("recommend"),
Keyword: keyword,
IncludePublic: true,
SearchOrderBy: orderBy,
Category: category,
Task: task,
License: license,
OwnerID: ownerID,
DatasetIDs: datasetsIds,
RecommendOnly: ctx.QueryBool("recommend"),
CloudBrainType: -1,
ListOptions: models.ListOptions{ ListOptions: models.ListOptions{
Page: page, Page: page,
PageSize: 30, PageSize: 30,


+ 120
- 35
routers/repo/cloudbrain.go View File

@@ -208,27 +208,14 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
displayJobName := form.DisplayJobName displayJobName := form.DisplayJobName
jobName := util.ConvertDisplayJobNameToJobName(displayJobName) jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
image := strings.TrimSpace(form.Image) image := strings.TrimSpace(form.Image)
uuid := form.Attachment
uuids := form.Attachment
jobType := form.JobType jobType := form.JobType
gpuQueue := form.GpuType gpuQueue := form.GpuType
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath
resourceSpecId := form.ResourceSpecId resourceSpecId := form.ResourceSpecId
branchName := form.BranchName branchName := form.BranchName
repo := ctx.Repo.Repository repo := ctx.Repo.Repository

tpl := tplCloudBrainNew tpl := tplCloudBrainNew
command := cloudbrain.Command
if jobType == string(models.JobTypeTrain) {
tpl = tplCloudBrainTrainJobNew
commandTrain, err := getTrainJobCommand(form)
if err != nil {
log.Error("getTrainJobCommand failed: %v", err)
ctx.RenderWithErr(err.Error(), tpl, &form)
return
}

command = commandTrain
}


tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName) tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName)
if err == nil { if err == nil {
@@ -274,6 +261,27 @@ 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)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}

command := cloudbrain.Command
if jobType == string(models.JobTypeTrain) {
tpl = tplCloudBrainTrainJobNew
commandTrain, err := getTrainJobCommand(form)
if err != nil {
log.Error("getTrainJobCommand failed: %v", err)
ctx.RenderWithErr(err.Error(), tpl, &form)
return
}

command = commandTrain
}

if branchName == "" { if branchName == "" {
branchName = cloudbrain.DefaultBranchName branchName = cloudbrain.DefaultBranchName
} }
@@ -286,11 +294,33 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {


commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName) commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName)


err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, branchName, form.BootFile, form.Params,
commitID, 0, 0, resourceSpecId)
req := cloudbrain.GenerateCloudBrainTaskReq{
Ctx: ctx,
DisplayJobName: displayJobName,
JobName: jobName,
Image: image,
Command: command,
Uuids: uuids,
DatasetNames: datasetNames,
DatasetInfos: datasetInfos,
CodePath: storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
ModelPath: storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
BenchmarkPath: storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"),
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"),
JobType: jobType,
GpuQueue: gpuQueue,
Description: form.Description,
BranchName: branchName,
BootFile: form.BootFile,
Params: form.Params,
CommitID: commitID,
BenchmarkTypeID: 0,
BenchmarkChildTypeID: 0,
ResourceSpecId: resourceSpecId,
}

err = cloudbrain.GenerateTask(req)
if err != nil { if err != nil {
cloudBrainNewDataPrepare(ctx) cloudBrainNewDataPrepare(ctx)
ctx.RenderWithErr(err.Error(), tpl, &form) ctx.RenderWithErr(err.Error(), tpl, &form)
@@ -575,12 +605,6 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
} }


} }
attachment, err := models.GetAttachmentByUUID(task.Uuid)
if err == nil {
ctx.Data["datasetname"] = attachment.Name
} else {
ctx.Data["datasetname"] = ""
}


ctx.Data["task"] = task ctx.Data["task"] = task
ctx.Data["jobName"] = task.JobName ctx.Data["jobName"] = task.JobName
@@ -2011,11 +2035,42 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo
//return //return
} }


err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, cloudbrain.DefaultBranchName, "", "",
"", benchmarkTypeID, benchmarkChildTypeID, resourceSpecId)
uuid := childInfo.Attachment
datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tplCloudBrainBenchmarkNew, &form)
return
}

req := cloudbrain.GenerateCloudBrainTaskReq{
Ctx: ctx,
DisplayJobName: displayJobName,
JobName: jobName,
Image: image,
Command: command,
Uuids: uuid,
DatasetNames: datasetNames,
DatasetInfos: datasetInfos,
CodePath: storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
ModelPath: storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
BenchmarkPath: storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"),
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"),
JobType: string(models.JobTypeBenchmark),
GpuQueue: gpuQueue,
Description: form.Description,
BranchName: cloudbrain.DefaultBranchName,
BootFile: "",
Params: "",
CommitID: "",
BenchmarkTypeID: benchmarkTypeID,
BenchmarkChildTypeID: benchmarkChildTypeID,
ResourceSpecId: resourceSpecId,
}

err = cloudbrain.GenerateTask(req)
if err != nil { if err != nil {
cloudBrainNewDataPrepare(ctx) cloudBrainNewDataPrepare(ctx)
ctx.RenderWithErr(err.Error(), tplCloudBrainBenchmarkNew, &form) ctx.RenderWithErr(err.Error(), tplCloudBrainBenchmarkNew, &form)
@@ -2109,11 +2164,41 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm)
command = fmt.Sprintf(cloudbrain.BrainScoreCommand, getBrainRegion(benchmarkChildTypeID), displayJobName, trimSpaceNewlineInString(form.Description)) command = fmt.Sprintf(cloudbrain.BrainScoreCommand, getBrainRegion(benchmarkChildTypeID), displayJobName, trimSpaceNewlineInString(form.Description))
} }


err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, branchName, form.BootFile, form.Params,
"", 0, benchmarkChildTypeID, resourceSpecId)
datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}

req := cloudbrain.GenerateCloudBrainTaskReq{
Ctx: ctx,
DisplayJobName: displayJobName,
JobName: jobName,
Image: image,
Command: command,
Uuids: uuid,
DatasetNames: datasetNames,
DatasetInfos: datasetInfos,
CodePath: storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
ModelPath: storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
BenchmarkPath: storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"),
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"),
JobType: jobType,
GpuQueue: gpuQueue,
Description: form.Description,
BranchName: branchName,
BootFile: form.BootFile,
Params: form.Params,
CommitID: "",
BenchmarkTypeID: 0,
BenchmarkChildTypeID: benchmarkChildTypeID,
ResourceSpecId: resourceSpecId,
}

err = cloudbrain.GenerateTask(req)
if err != nil { if err != nil {
cloudBrainNewDataPrepare(ctx) cloudBrainNewDataPrepare(ctx)
ctx.RenderWithErr(err.Error(), tpl, &form) ctx.RenderWithErr(err.Error(), tpl, &form)


+ 78
- 0
routers/repo/dataset.go View File

@@ -410,6 +410,84 @@ func MyDatasets(ctx *context.Context) {
}) })
} }


func datasetMultiple(ctx *context.Context, opts *models.SearchDatasetOptions) {
page := ctx.QueryInt("page")
cloudbrainType := ctx.QueryInt("type")
keyword := strings.Trim(ctx.Query("q"), " ")
orderBy := models.SearchOrderByRecentUpdated
opts.Keyword = keyword
opts.SearchOrderBy = orderBy
opts.RecommendOnly = ctx.QueryBool("recommend")
opts.CloudBrainType = cloudbrainType
opts.ListOptions = models.ListOptions{
Page: page,
PageSize: setting.UI.DatasetPagingNum,
}
opts.NeedAttachment = true
opts.JustNeedZipFile = true
opts.User = ctx.User

datasets, count, err := models.SearchDataset(opts)

if err != nil {
ctx.ServerError("datasets", err)
return
}

data, err := json.Marshal(datasets)
if err != nil {
log.Error("json.Marshal failed:", err.Error())
ctx.JSON(200, map[string]string{
"result_code": "-1",
"error_msg": err.Error(),
"data": "",
})
return
}
ctx.JSON(200, map[string]string{
"result_code": "0",
"data": string(data),
"count": strconv.FormatInt(count, 10),
})

}

func CurrentRepoDatasetMultiple(ctx *context.Context) {

opts := &models.SearchDatasetOptions{
RepoID: ctx.Repo.Repository.ID,
}
datasetMultiple(ctx, opts)

}

func MyDatasetsMultiple(ctx *context.Context) {

opts := &models.SearchDatasetOptions{
UploadAttachmentByMe: true,
}
datasetMultiple(ctx, opts)

}

func PublicDatasetMultiple(ctx *context.Context) {

opts := &models.SearchDatasetOptions{
PublicOnly: true,
}
datasetMultiple(ctx, opts)

}

func MyFavoriteDatasetMultiple(ctx *context.Context) {

opts := &models.SearchDatasetOptions{
StarByMe: true,
DatasetIDs: models.GetDatasetIdsStarByUser(ctx.User.ID),
}
datasetMultiple(ctx, opts)
}

func PublicDataset(ctx *context.Context) { func PublicDataset(ctx *context.Context) {
page := ctx.QueryInt("page") page := ctx.QueryInt("page")
cloudbrainType := ctx.QueryInt("type") cloudbrainType := ctx.QueryInt("type")


+ 6
- 6
routers/repo/grampus.go View File

@@ -422,7 +422,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
} }


//prepare command //prepare command
command, err := generateCommand(repo.Name, grampus.ProcessorTypeNPU, codeObsPath+cloudbrain.DefaultBranchName+".zip", dataObsPath+attachment.Name, bootFile, params, setting.CodePathPrefix+jobName+modelarts.OutputPath, attachment.Name)
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 { if err != nil {
log.Error("Failed to generateCommand: %s (%v)", displayJobName, err, ctx.Data["MsgID"]) log.Error("Failed to generateCommand: %s (%v)", displayJobName, err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
@@ -672,10 +672,10 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo
command += "pwd;cd " + workDir + grampus.CommandPrepareScript command += "pwd;cd " + workDir + grampus.CommandPrepareScript
//download code & dataset //download code & dataset
if processorType == grampus.ProcessorTypeNPU { if processorType == grampus.ProcessorTypeNPU {
commandDownload := "./downloader_for_obs " + setting.Bucket + " " + codeRemotePath + " " + grampus.CodeArchiveName + " " + dataRemotePath + " " + datasetName + ";"
commandDownload := "./downloader_for_obs " + setting.Bucket + " " + codeRemotePath + " " + grampus.CodeArchiveName + " " + dataRemotePath + " '" + datasetName + "';"
command += commandDownload command += commandDownload
} else if processorType == grampus.ProcessorTypeGPU { } else if processorType == grampus.ProcessorTypeGPU {
commandDownload := "./downloader_for_minio " + setting.Grampus.Env + " " + codeRemotePath + " " + grampus.CodeArchiveName + " " + dataRemotePath + " " + datasetName + ";"
commandDownload := "./downloader_for_minio " + setting.Grampus.Env + " " + codeRemotePath + " " + grampus.CodeArchiveName + " " + dataRemotePath + " '" + datasetName + "';"
command += commandDownload command += commandDownload
} }


@@ -684,11 +684,11 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo
command += commandCheckRes command += commandCheckRes


//unzip code & dataset //unzip code & dataset
toolUnzip := "unzip -q "
toolUnzip := "unzip -q '"
if strings.HasSuffix(datasetName, ".tar.gz") { if strings.HasSuffix(datasetName, ".tar.gz") {
toolUnzip = "tar -zxvf "
toolUnzip = "tar -zxvf '"
} }
commandUnzip := "cd " + workDir + "code;unzip -q master.zip;echo \"start to unzip dataset\";cd " + workDir + "dataset;" + toolUnzip + datasetName + ";"
commandUnzip := "cd " + workDir + "code;unzip -q master.zip;echo \"start to unzip dataset\";cd " + workDir + "dataset;" + toolUnzip + datasetName + "';"
command += commandUnzip command += commandUnzip


//check unzip result //check unzip result


+ 123
- 8
routers/repo/modelarts.go View File

@@ -285,14 +285,37 @@ func NotebookShow(ctx *context.Context) {
} }
} }


datasetDownloadLink := ""
datasetDownload := make([]models.DatasetDownload, 0)
if ctx.IsSigned { if ctx.IsSigned {
if task.Uuid != "" && task.UserID == ctx.User.ID { if task.Uuid != "" && task.UserID == ctx.User.ID {
attachment, err := models.GetAttachmentByUUID(task.Uuid)
if err == nil {
task.DatasetName = attachment.Name
datasetDownloadLink = attachment.S3DownloadURL()
uuidList := strings.Split(task.Uuid, ";")
for _, uuidStr := range uuidList {
attachment, err := models.GetAttachmentByUUID(uuidStr)
if err != nil {
log.Error("GetAttachmentByUUID failed:%v", err.Error())
return
}
dataset, err := models.GetDatasetByID(attachment.DatasetID)
if err != nil {
log.Error("GetDatasetByID failed:%v", err.Error())
return
}
repo, err := models.GetRepositoryByID(dataset.RepoID)
if err != nil {
log.Error("GetRepositoryByID failed:%v", err.Error())
return
}
datasetDownload = append(datasetDownload, models.DatasetDownload{
DatasetName: attachment.Name,
DatasetDownloadLink: attachment.S3DownloadURL(),
RepositoryLink: repo.Link() + "/datasets",
})

} }
// datasetName, err := GetDatasetNameByUUID(task.Uuid)
// if err == nil {
// task.DatasetName = datasetName
// }
} }
} }
user, err := models.GetUserByID(task.UserID) user, err := models.GetUserByID(task.UserID)
@@ -324,7 +347,7 @@ func NotebookShow(ctx *context.Context) {
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) task.TrainJobDuration = models.ConvertDurationToStr(task.Duration)
} }
ctx.Data["duration"] = task.TrainJobDuration ctx.Data["duration"] = task.TrainJobDuration
ctx.Data["datasetDownloadLink"] = datasetDownloadLink
ctx.Data["datasetDownload"] = datasetDownload
ctx.Data["task"] = task ctx.Data["task"] = task
ctx.Data["ID"] = ID ctx.Data["ID"] = ID
ctx.Data["jobName"] = task.JobName ctx.Data["jobName"] = task.JobName
@@ -962,7 +985,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath
outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/" outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/"
logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/" logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/"
dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
// dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
branch_name := form.BranchName branch_name := form.BranchName
isLatestVersion := modelarts.IsLatestVersion isLatestVersion := modelarts.IsLatestVersion
FlavorName := form.FlavorName FlavorName := form.FlavorName
@@ -1078,6 +1101,27 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
Value: modelarts.Ascend, Value: modelarts.Ascend,
}) })
} }
datasUrlList, dataUrl, datasetNames, isMultiDataset, err := getDatasUrlListByUUIDS(uuid)
if err != nil {
log.Error("Failed to getDatasUrlListByUUIDS: %v", err)
trainJobErrorNewDataPrepare(ctx, form)
ctx.RenderWithErr("Failed to getDatasUrlListByUUIDS:"+err.Error(), tplModelArtsTrainJobNew, &form)
return
}
dataPath := dataUrl
jsondatas, err := json.Marshal(datasUrlList)
if err != nil {
log.Error("Failed to Marshal: %v", err)
trainJobErrorNewDataPrepare(ctx, form)
ctx.RenderWithErr("json error:"+err.Error(), tplModelArtsTrainJobNew, &form)
return
}
if isMultiDataset {
param = append(param, models.Parameter{
Label: modelarts.MultiDataUrl,
Value: string(jsondatas),
})
}


//save param config //save param config
if isSaveParam == "on" { if isSaveParam == "on" {
@@ -1144,6 +1188,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
EngineName: EngineName, EngineName: EngineName,
VersionCount: VersionCount, VersionCount: VersionCount,
TotalVersionCount: modelarts.TotalVersionCount, TotalVersionCount: modelarts.TotalVersionCount,
DatasetName: datasetNames,
} }


//将params转换Parameters.Parameter,出错时返回给前端 //将params转换Parameters.Parameter,出错时返回给前端
@@ -1205,7 +1250,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath + VersionOutputPath + "/" codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath + VersionOutputPath + "/"
outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/" outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/"
logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/" logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/"
dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
// dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
branch_name := form.BranchName branch_name := form.BranchName
PreVersionName := form.VersionName PreVersionName := form.VersionName
FlavorName := form.FlavorName FlavorName := form.FlavorName
@@ -1297,6 +1342,28 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
}) })
} }


datasUrlList, dataUrl, datasetNames, isMultiDataset, err := getDatasUrlListByUUIDS(uuid)
if err != nil {
log.Error("Failed to getDatasUrlListByUUIDS: %v", err)
versionErrorDataPrepare(ctx, form)
ctx.RenderWithErr("Failed to getDatasUrlListByUUIDS:"+err.Error(), tplModelArtsTrainJobVersionNew, &form)
return
}
dataPath := dataUrl
jsondatas, err := json.Marshal(datasUrlList)
if err != nil {
log.Error("Failed to Marshal: %v", err)
versionErrorDataPrepare(ctx, form)
ctx.RenderWithErr("json error:"+err.Error(), tplModelArtsTrainJobVersionNew, &form)
return
}
if isMultiDataset {
param = append(param, models.Parameter{
Label: modelarts.MultiDataUrl,
Value: string(jsondatas),
})
}

//save param config //save param config
if isSaveParam == "on" { if isSaveParam == "on" {
saveparams := append(param, models.Parameter{ saveparams := append(param, models.Parameter{
@@ -1369,6 +1436,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
EngineName: EngineName, EngineName: EngineName,
PreVersionName: PreVersionName, PreVersionName: PreVersionName,
TotalVersionCount: latestTask.TotalVersionCount + 1, TotalVersionCount: latestTask.TotalVersionCount + 1,
DatasetName: datasetNames,
} }


err = modelarts.GenerateTrainJobVersion(ctx, req, jobID) err = modelarts.GenerateTrainJobVersion(ctx, req, jobID)
@@ -2414,3 +2482,50 @@ func TrainJobDownloadLogFile(ctx *context.Context) {
ctx.Resp.Header().Set("Cache-Control", "max-age=0") ctx.Resp.Header().Set("Cache-Control", "max-age=0")
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
} }
func getDatasUrlListByUUIDS(uuidStr string) ([]models.Datasurl, string, string, bool, error) {
var isMultiDataset bool
var dataUrl string
var datasetNames string
var datasUrlList []models.Datasurl
uuids := strings.Split(uuidStr, ";")
if len(uuids) > setting.MaxDatasetNum {
log.Error("the dataset count(%d) exceed the limit", len(uuids))
return datasUrlList, dataUrl, datasetNames, isMultiDataset, errors.New("the dataset count exceed the limit")
}

datasetInfos := make(map[string]models.DatasetInfo)
attachs, err := models.GetAttachmentsByUUIDs(uuids)
if err != nil {
log.Error("GetAttachmentsByUUIDs failed: %v", err)
return datasUrlList, dataUrl, datasetNames, isMultiDataset, errors.New("GetAttachmentsByUUIDs failed")
}
for i, attach := range attachs {
fileName := strings.TrimSuffix(strings.TrimSuffix(strings.TrimSuffix(attach.Name, ".zip"), ".tar.gz"), ".tgz")
for _, datasetInfo := range datasetInfos {
if fileName == datasetInfo.Name {
log.Error("the dataset name is same: %v", attach.Name)
return datasUrlList, dataUrl, datasetNames, isMultiDataset, errors.New("the dataset name is same")
}
}
if len(attachs) <= 1 {
dataUrl = "/" + setting.Bucket + "/" + setting.BasePath + path.Join(attach.UUID[0:1], attach.UUID[1:2]) + "/" + attach.UUID + attach.UUID + "/"
isMultiDataset = false
} else {
dataUrl = "/" + setting.Bucket + "/" + setting.BasePath + path.Join(attachs[0].UUID[0:1], attachs[0].UUID[1:2]) + "/" + attachs[0].UUID + attachs[0].UUID + "/"
datasetUrl := "s3://" + setting.Bucket + "/" + setting.BasePath + path.Join(attach.UUID[0:1], attach.UUID[1:2]) + "/" + attach.UUID + attach.UUID + "/"
datasUrlList = append(datasUrlList, models.Datasurl{
DatasetUrl: datasetUrl,
DatasetName: fileName,
})
isMultiDataset = true
}

if i == 0 {
datasetNames = attach.Name
} else {
datasetNames += ";" + attach.Name
}
}

return datasUrlList, dataUrl, datasetNames, isMultiDataset, nil
}

+ 5
- 0
routers/routes/routes.go View File

@@ -1026,6 +1026,11 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/public_datasets", repo.PublicDataset) m.Get("/public_datasets", repo.PublicDataset)
m.Get("/my_favorite", repo.MyFavoriteDataset) m.Get("/my_favorite", repo.MyFavoriteDataset)


m.Get("/current_repo_m", repo.CurrentRepoDatasetMultiple)
m.Get("/my_datasets_m", repo.MyDatasetsMultiple)
m.Get("/public_datasets_m", repo.PublicDatasetMultiple)
m.Get("/my_favorite_m", repo.MyFavoriteDatasetMultiple)

m.Group("/status", func() { m.Group("/status", func() {
m.Get("/:uuid", repo.GetDatasetStatus) m.Get("/:uuid", repo.GetDatasetStatus)
}) })


+ 1
- 0
routers/user/profile.go View File

@@ -263,6 +263,7 @@ func Profile(ctx *context.Context) {
Page: page, Page: page,
PageSize: setting.UI.ExplorePagingNum, PageSize: setting.UI.ExplorePagingNum,
}, },
CloudBrainType: -1,
} }


if len(datasetSearchOptions.SearchOrderBy) == 0 { if len(datasetSearchOptions.SearchOrderBy) == 0 {


+ 2
- 2
templates/custom/select_dataset_train.tmpl View File

@@ -1,11 +1,11 @@
<div class="dataset-repolink" id="dataset-repolink-init" style="display: none;" data-repolink="{{.RepoLink}}" <div class="dataset-repolink" id="dataset-repolink-init" style="display: none;" data-repolink="{{.RepoLink}}"
data-dataset-type="{{.datasetType}}"></div> data-dataset-type="{{.datasetType}}"></div>
<div class="inline required unite min_title field" id="dataset-base" style="margin-bottom: 0 !important;">
<div class="inline required min_title field" id="dataset-base" style="margin-bottom: 0 !important;">
{{if or (.benchmarkMode) (.newInference)}} {{if or (.benchmarkMode) (.newInference)}}
<label <label
style="font-weight: normal;">{{if .benchmarkMode}}{{.i18n.Tr "repo.model_manager"}}</label><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>{{else}}{{.i18n.Tr "dataset.dataset"}}</label>&nbsp;&nbsp;&nbsp;&nbsp;{{end}} style="font-weight: normal;">{{if .benchmarkMode}}{{.i18n.Tr "repo.model_manager"}}</label><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>{{else}}{{.i18n.Tr "dataset.dataset"}}</label>&nbsp;&nbsp;&nbsp;&nbsp;{{end}}
{{else}} {{else}}
<label style="font-weight: normal;">{{.i18n.Tr "dataset.dataset"}}</label>&nbsp;&nbsp;&nbsp;
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "dataset.dataset"}}</label>
{{end}} {{end}}
<input type="hidden" name="attachment" :value="dataset_uuid"> <input type="hidden" name="attachment" :value="dataset_uuid">
<input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();" style="width: 48.5%;"> <input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();" style="width: 48.5%;">


+ 1
- 1
templates/explore/datasets.tmpl View File

@@ -154,7 +154,7 @@
<a class="{{if eq .SortType "downloadtimes"}}active{{end}} item" <a class="{{if eq .SortType "downloadtimes"}}active{{end}} item"
href="{{$.Link}}?sort=downloadtimes&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}&recommend={{$.Recommend}}">{{.i18n.Tr "repo.issues.filter_sort.downloadtimes"}}</a> href="{{$.Link}}?sort=downloadtimes&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}&recommend={{$.Recommend}}">{{.i18n.Tr "repo.issues.filter_sort.downloadtimes"}}</a>
<a class="{{if eq .SortType "moststars"}}active{{end}} item" <a class="{{if eq .SortType "moststars"}}active{{end}} item"
href="{{$.Link}}?sort=moststars&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}&recommend={{$.Recommend}}">{{.i18n.Tr "repo.issues.filter_sort.moststars"}}</a>
href="{{$.Link}}?sort=moststars&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}&recommend={{$.Recommend}}">{{.i18n.Tr "dataset.collection_num"}}</a>
<a class="{{if eq .SortType "mostusecount"}}active{{end}} item" <a class="{{if eq .SortType "mostusecount"}}active{{end}} item"
href="{{$.Link}}?sort=mostusecount&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}&recommend={{$.Recommend}}">{{.i18n.Tr "repo.issues.filter_sort.mostusecount"}}</a> href="{{$.Link}}?sort=mostusecount&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}&recommend={{$.Recommend}}">{{.i18n.Tr "repo.issues.filter_sort.mostusecount"}}</a>
</div> </div>


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

@@ -474,7 +474,7 @@


<td class="ti-text-form-content"> <td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> <div class="text-span text-span-w" id="{{.VersionName}}-mirror">
{{$.datasetname}}
{{.DatasetName}}
</div> </div>
</td> </td>
</tr> </tr>


+ 5
- 5
templates/repo/cloudbrain/new.tmpl View File

@@ -104,6 +104,7 @@
top: 14px; top: 14px;
z-index: 2; */ z-index: 2; */
} }

</style> </style>


<div id="mask"> <div id="mask">
@@ -119,8 +120,8 @@
<div class="repository"> <div class="repository">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="repository new repo ui middle very relaxed page grid"> <div class="repository new repo ui middle very relaxed page grid">

<div class="column"> <div class="column">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
{{template "base/alert" .}} {{template "base/alert" .}}
<div class="ui negative message" id="messageInfo"> <div class="ui negative message" id="messageInfo">
<p></p> <p></p>
@@ -218,8 +219,10 @@
<div id="images-new-cb"> <div id="images-new-cb">


</div> </div>
<div id="select-multi-dataset">


{{template "custom/select_dataset" .}}
</div>
<div class="inline required field"> <div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="cloudbrain_resource_spec" class="ui search dropdown" <select id="cloudbrain_resource_spec" class="ui search dropdown"
@@ -278,8 +281,6 @@
</div> </div>
</div> </div>
</form> </form>


</div> </div>
</div> </div>
</div> </div>
@@ -373,5 +374,4 @@
$('#store_category').attr("value", selected_value) $('#store_category').attr("value", selected_value)
}) })



</script> </script>

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

@@ -409,7 +409,7 @@
<td class="ti-text-form-content"> <td class="ti-text-form-content">
<div class="text-span text-span-w" <div class="text-span text-span-w"
id="{{.VersionName}}-BenchmarkTypeName"> id="{{.VersionName}}-BenchmarkTypeName">
{{$.datasetname}}
{{.DatasetName}}
</div> </div>
</td> </td>
</tr> </tr>


+ 50
- 52
templates/repo/cloudbrain/trainjob/new.tmpl View File

@@ -1,20 +1,14 @@
{{template "base/head" .}} {{template "base/head" .}}
<style> <style>
.unite {
.train-job-title {
font-family: SourceHanSansSC-medium !important; font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important; color: rgba(16, 16, 16, 100) !important;
}

.title {
font-size: 16px !important; font-size: 16px !important;
padding-left: 3rem !important; padding-left: 3rem !important;
} }

.min_title {
.min_title{
font-size: 14px !important; font-size: 14px !important;
padding-left: 6rem !important;
margin-bottom: 2rem !important; margin-bottom: 2rem !important;

} }


.width { .width {
@@ -33,9 +27,10 @@


.width85 { .width85 {
width: 85% !important; width: 85% !important;
margin-left: 4.5rem !important;
margin-left: 10.5rem !important;
align-items: center;
} }
.width81 { .width81 {
margin-left: 1.5rem !important; margin-left: 1.5rem !important;
width: 81% !important; width: 81% !important;
@@ -60,6 +55,14 @@
text-align: center; text-align: center;
color: #C2C7CC; color: #C2C7CC;
} }
.label-fix-width{
width: 140px !important;
text-align: right;
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 14px !important;
}

</style> </style>
<!-- <div class="ui page dimmer"> <!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div> <div class="ui text loader">{{.i18n.Tr "loading"}}</div>
@@ -76,6 +79,7 @@
<div class="repository"> <div class="repository">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
{{template "base/alert" .}} {{template "base/alert" .}}
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new"}} {{.i18n.Tr "repo.modelarts.train_job.new"}}
@@ -87,22 +91,22 @@
<input type="hidden" name="action" value="update"> <input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> <input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> <input type="hidden" id="ai_flaver_name" name="flaver_names" value="">
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field"> <div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create"> <a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}} {{.i18n.Tr "cloudbrain.resource_cluster_openi"}}
</a> </a>
<a class="item" href="{{.RepoLink}}/grampus/train-job/npu/create"> <a class="item" href="{{.RepoLink}}/grampus/train-job/npu/create">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta)
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta)
</a> </a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create"> <a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16"
@@ -123,18 +127,18 @@
Ascend NPU</a> Ascend NPU</a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 60%;" name="display_job_name" id="display_job_name" <input style="width: 60%;" name="display_job_name" id="display_job_name"
placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}"
tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required
maxlength="64"> maxlength="64">
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
<span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
</div> </div>


<div class="unite min_title inline field">
<label style="font-weight: normal;"
for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label>
<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" <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255"
placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}
onchange="this.value=this.value.substring(0, 255)" onchange="this.value=this.value.substring(0, 255)"
@@ -143,11 +147,11 @@
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>


<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>




<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" id="code_version" name="branch_name"> <select class="ui dropdown width80 left2" id="code_version" name="branch_name">
{{if .branch_name}} {{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
@@ -175,8 +179,8 @@
</select> </select>
</div> </div>


<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<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" placeholder="选择GPU类型" <select id="cloudbrain_gpu_type" class="ui search width806 dropdown" placeholder="选择GPU类型"
style='width:385px' name="gpu_type"> style='width:385px' name="gpu_type">
{{range .train_gpu_types}} {{range .train_gpu_types}}
@@ -184,27 +188,12 @@
{{end}} {{end}}
</select> </select>
</div> </div>

<!-- <div class="required unite min_title inline field" style="position: relative;">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}&nbsp;</label>
<input class="width81" type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" required autofocus maxlength="255">
<i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i>
<datalist class="ui search" id="cloudbrain_image" name="image">
{{range .images}}
<option name="image" value="{{.Place}}">{{.PlaceView}}</option>
{{end}}
{{range .public_images}}
<option name="image" value="{{.Place}}">{{.PlaceView}}</option>
{{end}}
</datalist>
</div> -->

<div id="images-new-cb"> <div id="images-new-cb">


</div> </div>


<div class="inline unite min_title field required">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
<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}} {{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}"
tabindex="3" autofocus required maxlength="255"> tabindex="3" autofocus required maxlength="255">
@@ -219,13 +208,17 @@
</span> </span>
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a> <a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a>
</div> </div>
<div id="select-multi-dataset">

</div>




{{template "custom/select_dataset_train" .}}
<!-- {{template "custom/select_dataset_train" .}} -->
<span class="tooltips" <span class="tooltips"
style="margin-left: 11.5rem;margin-bottom: 2rem;">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span>
<div class="inline unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
style="margin-left: 11.5rem;margin-bottom: 1rem;">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span>
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<span id="add_run_para" <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 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> class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span>
@@ -252,8 +245,8 @@
</div> </div>
</div> </div>


<div class="required inline unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<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="选择资源规格" <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格"
style='width:385px' name="resource_spec_id"> style='width:385px' name="resource_spec_id">
{{range .train_resource_specs}} {{range .train_resource_specs}}
@@ -263,7 +256,8 @@
</select> </select>
</div> </div>


<div class="inline unite min_title field">
<div class="inline field" style="padding: 1rem 0;">
<label class="label-fix-width"></label>
<button class="ui create_train_job green button"> <button class="ui create_train_job green button">
{{.i18n.Tr "repo.cloudbrain.new"}} {{.i18n.Tr "repo.cloudbrain.new"}}
</button> </button>
@@ -287,7 +281,11 @@


$('.menu .item') $('.menu .item')
.tab(); .tab();

$(document).keydown(function(event){
switch(event.keyCode){
case 13:return false;
}
});
let sever_num = $('#trainjob_work_server_num') let sever_num = $('#trainjob_work_server_num')
$('.add').click(function () { $('.add').click(function () {
sever_num.val(parseInt(sever_num.val()) + 1) sever_num.val(parseInt(sever_num.val()) + 1)


+ 32
- 30
templates/repo/grampus/trainjob/gpu/new.tmpl View File

@@ -1,20 +1,15 @@
{{template "base/head" .}} {{template "base/head" .}}
<style> <style>


.unite{
.train-job-title {
font-family: SourceHanSansSC-medium !important; font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important; color: rgba(16, 16, 16, 100) !important;
}

.title{
font-size: 16px !important; font-size: 16px !important;
padding-left: 3rem !important; padding-left: 3rem !important;
} }
.min_title{ .min_title{
font-size: 14px !important; font-size: 14px !important;
padding-left: 6rem !important;
margin-bottom: 2rem !important; margin-bottom: 2rem !important;

} }
.width{ .width{
width:100% !important; width:100% !important;
@@ -29,10 +24,10 @@
} }
.width85{ .width85{
width: 85% !important; width: 85% !important;
margin-left: 4.5rem !important;
margin-left: 10.5rem !important;
align-items: center;
} }
.width81{ .width81{
margin-left: 1.5rem !important;
width: 81% !important; width: 81% !important;
} }


@@ -53,7 +48,13 @@
text-align: center; text-align: center;
color: #C2C7CC; color: #C2C7CC;
} }

.label-fix-width{
width: 140px !important;
text-align: right;
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 14px !important;
}
</style> </style>
<!-- <div class="ui page dimmer"> <!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div> <div class="ui text loader">{{.i18n.Tr "loading"}}</div>
@@ -81,22 +82,22 @@
<input type="hidden" name="action" value="update"> <input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> <input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flavor_name" name="flavor_name" value=""> <input type="hidden" id="ai_flavor_name" name="flavor_name" value="">
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
<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>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create"> <a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}} {{.i18n.Tr "cloudbrain.resource_cluster_openi"}}
</a> </a>
<a class="active item" href="{{.RepoLink}}/grampus/train-job/ {{if.NPUEnabled}}npu{{else}}gpu{{end}}/create">
<a class="active item" href="{{.RepoLink}}/grampus/train-job/{{if.NPUEnabled}}npu{{else}}gpu{{end}}/create">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta)
</a> </a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a {{if.GPUEnabled}}class="active item" href="{{.RepoLink}}/grampus/train-job/gpu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}}> <a {{if.GPUEnabled}}class="active item" href="{{.RepoLink}}/grampus/train-job/gpu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}}>
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
@@ -113,23 +114,23 @@
Ascend NPU</a> Ascend NPU</a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64">
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
<span class="tooltips" style="margin-left: 11.5rem;display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
</div> </div>
<div class="unite min_title inline field">
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label>
<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>
<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> <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>
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>


<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>


<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" id="code_version" name="branch_name"> <select class="ui dropdown width80 left2" id="code_version" name="branch_name">
{{if .branch_name}} {{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
@@ -152,8 +153,8 @@
<div id="images-new-grampus"> <div id="images-new-grampus">
</div> </div>


<div class="inline unite min_title field required">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
<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}} {{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{else}} {{else}}
@@ -168,8 +169,8 @@
{{template "custom/select_dataset_train" .}} {{template "custom/select_dataset_train" .}}
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.grampus.gpu_dataset_path_rule"}}</span> <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.grampus.gpu_dataset_path_rule"}}</span>
<div class="inline unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span>
<input id="store_run_para" type="hidden" name="run_para_list"> <input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;"> <div class="dynamic field" style="margin-top: 1rem;">
@@ -194,8 +195,8 @@
</div> </div>
</div> </div>


<div class="required unite min_title inline field" id="flavor_name">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<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"> <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor">
{{range .flavor_infos}} {{range .flavor_infos}}
<option name="flavor" value="{{.ID}}">{{.Name}}</option> <option name="flavor" value="{{.ID}}">{{.Name}}</option>
@@ -203,7 +204,8 @@
</select> </select>
</div> </div>
<div class="inline unite min_title field">
<div class="inline min_title field">
<label class="label-fix-width"></label>
<button class="ui create_train_job green button"> <button class="ui create_train_job green button">
{{.i18n.Tr "repo.cloudbrain.new"}} {{.i18n.Tr "repo.cloudbrain.new"}}
</button> </button>


+ 34
- 33
templates/repo/grampus/trainjob/npu/new.tmpl View File

@@ -1,20 +1,14 @@
{{template "base/head" .}} {{template "base/head" .}}
<style> <style>

.unite{
.train-job-title {
font-family: SourceHanSansSC-medium !important; font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important; color: rgba(16, 16, 16, 100) !important;
}

.title{
font-size: 16px !important; font-size: 16px !important;
padding-left: 3rem !important; padding-left: 3rem !important;
} }
.min_title{ .min_title{
font-size: 14px !important; font-size: 14px !important;
padding-left: 6rem !important;
margin-bottom: 2rem !important; margin-bottom: 2rem !important;

} }
.width{ .width{
width:100% !important; width:100% !important;
@@ -25,10 +19,10 @@
} }
.width85{ .width85{
width: 85% !important; width: 85% !important;
margin-left: 4.5rem !important;
margin-left: 10.5rem !important;
align-items: center;
} }
.width81{ .width81{
margin-left: 1.5rem;
width: 81% !important; width: 81% !important;
} }


@@ -49,7 +43,13 @@
text-align: center; text-align: center;
color: #C2C7CC; color: #C2C7CC;
} }

.label-fix-width{
width: 140px !important;
text-align: right;
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 14px !important;
}
</style> </style>
<!-- <div class="ui page dimmer"> <!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div> <div class="ui text loader">{{.i18n.Tr "loading"}}</div>
@@ -77,22 +77,22 @@
<input type="hidden" name="action" value="update"> <input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_name" value=""> <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="ai_flavor_name" name="flavor_name" value="">
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
<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>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create"> <a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}} {{.i18n.Tr "cloudbrain.resource_cluster_openi"}}
</a> </a>
<a class="active item" href="{{.RepoLink}}/grampus/train-job/ {{if.NPUEnabled}}npu{{else}}gpu{{end}}/create">
<a class="active item" href="{{.RepoLink}}/grampus/train-job/{{if.NPUEnabled}}npu{{else}}gpu{{end}}/create">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta)
</a> </a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a {{if.GPUEnabled}}class="item" href="{{.RepoLink}}/grampus/train-job/gpu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}}> <a {{if.GPUEnabled}}class="item" href="{{.RepoLink}}/grampus/train-job/gpu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}}>
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
@@ -109,23 +109,23 @@
Ascend NPU</a> Ascend NPU</a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64">
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
</div> </div>


<div class="unite min_title inline field">
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label>
<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>
<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> <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>
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>


<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<h4 class="train-job-title title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>




<div class="required unite min_title inline field"> <div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" id="code_version" name="branch_name"> <select class="ui dropdown width80 left2" id="code_version" name="branch_name">
{{if .branch_name}} {{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
@@ -145,8 +145,8 @@
</select> </select>
</div> </div>


<div class="required unite min_title inline field" id="engine_name">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label>
<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"> <select class="ui dropdown width81" id="trainjob_images" name="image_id">
{{range .images}} {{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option> <option name="image_id" value="{{.ID}}">{{.Name}}</option>
@@ -154,8 +154,8 @@
</select> </select>
</div> </div>


<div class="inline unite min_title field required">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
<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}} {{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{else}} {{else}}
@@ -169,24 +169,24 @@
{{template "custom/select_dataset_train" .}} {{template "custom/select_dataset_train" .}}
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.grampus.dataset_path_rule"}}</span> <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.grampus.dataset_path_rule"}}</span>
<div class="inline unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span>
<input id="store_run_para" type="hidden" name="run_para_list"> <input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;"> <div class="dynamic field" style="margin-top: 1rem;">
</div> </div>
</div> </div>


<div class="required unite min_title inline field" id="flavor_name">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<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"> <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor">
{{range .flavor_infos}} {{range .flavor_infos}}
<option name="flavor" value="{{.ID}}">{{.Name}}</option> <option name="flavor" value="{{.ID}}">{{.Name}}</option>
{{end}} {{end}}
</select> </select>
</div> </div>
<div class="inline required unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<div class="inline required min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>


<div class="ui labeled input" style="width: 5%;"> <div class="ui labeled input" style="width: 5%;">


@@ -200,7 +200,8 @@
</div> </div>
</div> </div>


<div class="inline unite min_title field">
<div class="inline min_title field">
<label class="label-fix-width"></label>
<button class="ui create_train_job green button"> <button class="ui create_train_job green button">
{{.i18n.Tr "repo.cloudbrain.new"}} {{.i18n.Tr "repo.cloudbrain.new"}}
</button> </button>


+ 4
- 1
templates/repo/modelarts/notebook/new.tmpl View File

@@ -18,6 +18,7 @@
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="repository new repo ui middle very relaxed page grid"> <div class="repository new repo ui middle very relaxed page grid">
<div class="column"> <div class="column">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
{{template "base/alert" .}} {{template "base/alert" .}}
<div class="ui negative message" id="messageInfo"> <div class="ui negative message" id="messageInfo">
<p></p> <p></p>
@@ -59,7 +60,9 @@
{{end}} {{end}}
</select> </select>
</div> </div>
{{template "custom/select_dataset" .}}
<div id="select-multi-dataset">

</div>


<!--<div class="inline required field"> <!--<div class="inline required field">
<label>工作环境</label> <label>工作环境</label>


+ 32
- 44
templates/repo/modelarts/notebook/show.tmpl View File

@@ -69,7 +69,6 @@
} }


.tab_2_content { .tab_2_content {
min-height: 460px;
margin-left: 10px; margin-left: 10px;
} }


@@ -338,30 +337,6 @@
</div> </div>
</td> </td>
</tr> </tr>

<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-duration">
{{$.duration}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.datasetdownload"}}
</td>

<td class="ti-text-form-content">
<div class="text-span-new" id="model_description">
{{$.datasetDownloadLink}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate"> <tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80"> <td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.description"}} {{$.i18n.Tr "cloudbrain.description"}}
@@ -392,24 +367,6 @@
</div> </div>
</td> </td>
</tr> </tr>



<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.train_job.dataset"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-BenchmarkTypeName">
{{.DatasetName}}
</div>
</td>
</tr>



<tr class="ti-no-ng-animate"> <tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80"> <td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} {{$.i18n.Tr "repo.modelarts.train_job.standard"}}
@@ -456,6 +413,18 @@
</div> </div>
</td> </td>
</tr> </tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-duration">
{{$.duration}}
</div>
</td>
</tr>




</tbody> </tbody>
@@ -463,8 +432,26 @@
</div> </div>
</div> </div>


</div> </div>

<div style="clear:both">
<table style="border:none" class="ui fixed small stackable table">
<thead>
<tr><th style="color: #8a8e99;font-size:12px" class="three wide center aligned">数据集文件</th>
<th style="color: #8a8e99;font-size:12px"class="eleven wide">数据集下载地址</th>
<th style="color: #8a8e99;font-size:12px" class="two wide center aligned">操作</th>
</tr></thead>
<tbody>
{{range $.datasetDownload}}
<tr>
<td style="word-wrap: break-word;word-break: break-all;"><a href="{{.RepositoryLink}}">{{.DatasetName}}</a></td>
<td style="word-wrap: break-word;word-break: break-all;">{{.DatasetDownloadLink}}</td>
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{.DatasetDownloadLink}}">复制链接</a></td>
</tr>
{{end}}
</tbody>
</table>
</div>
</div> </div>
</div> </div>


@@ -509,4 +496,5 @@
$(document).ready(function () { $(document).ready(function () {
$('.secondary.menu .item').tab(); $('.secondary.menu .item').tab();
}); });
console.log({{$.datasetDownload}})
</script> </script>

+ 123
- 135
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -1,59 +1,58 @@
{{template "base/head" .}} {{template "base/head" .}}
<style> <style>
.unite {
.train-job-title {
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
}
.width{
width:100% !important;
}
.width48{
width: 48.5% !important;
}
.width80{
width: 80.7% !important;
margin-left: 10px;
}
.width85{
width: 85% !important;
margin-left: 10.5rem !important;
align-items: center;
}
.width81{
margin-left: 1.5rem;
width: 81% !important;
}

.add{font-size: 18px;
padding: 0.5rem;
border: 1px solid rgba(187, 187, 187, 100);
border-radius: 0px 5px 5px 0px;
line-height: 21px;
text-align: center;
color: #C2C7CC;
}
.min{
font-size: 18px;
padding: 0.5rem;
border: 1px solid rgba(187, 187, 187, 100);
border-radius: 5px 0px 0px 5px;
line-height: 21px;
text-align: center;
color: #C2C7CC;
}
.label-fix-width{
width: 140px !important;
text-align: right;
font-family: SourceHanSansSC-medium !important; font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important; color: rgba(16, 16, 16, 100) !important;
}

.title {
font-size: 16px !important;
padding-left: 3rem !important;
}

.min_title {
font-size: 14px !important; font-size: 14px !important;
padding-left: 6rem !important;
margin-bottom: 2rem !important;

}

.width {
width: 100% !important;
}

.width80 {
width: 80.7% !important;
margin-left: 10px;
}

.width85 {
width: 85% !important;
margin-left: 4.5rem !important;
}

.width81 {
margin-left: 1.5rem;
width: 81% !important;
}

.add {
font-size: 18px;
padding: 0.5rem;
border: 1px solid rgba(187, 187, 187, 100);
border-radius: 0px 5px 5px 0px;
line-height: 21px;
text-align: center;
color: #C2C7CC;
}

.min {
font-size: 18px;
padding: 0.5rem;
border: 1px solid rgba(187, 187, 187, 100);
border-radius: 5px 0px 0px 5px;
line-height: 21px;
text-align: center;
color: #C2C7CC;
} }
</style> </style>
<!-- <div class="ui page dimmer"> <!-- <div class="ui page dimmer">
@@ -71,6 +70,7 @@
<div class="repository"> <div class="repository">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
{{template "base/alert" .}} {{template "base/alert" .}}
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new"}} {{.i18n.Tr "repo.modelarts.train_job.new"}}
@@ -82,9 +82,9 @@
<input type="hidden" name="action" value="update"> <input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> <input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> <input type="hidden" id="ai_flaver_name" name="flaver_names" value="">
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
<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>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create"> <a class="active item" href="{{.RepoLink}}/cloudbrain/train-job/create">
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg>
@@ -96,8 +96,8 @@
</a> </a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="required inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue mini menu compact selectcloudbrain"> <div class="ui blue mini menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create"> <a class="item" href="{{.RepoLink}}/cloudbrain/train-job/create">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16"
@@ -118,55 +118,46 @@
Ascend NPU</a> Ascend NPU</a>
</div> </div>
</div> </div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 60%;" name="display_job_name" id="display_job_name"
placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}"
tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required
maxlength="64">
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
<div class="required inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64">
<span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
</div> </div>


<div class="unite min_title inline field">
<label style="font-weight: normal;"
for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</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>
<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>
</div> </div>
<div class="ui divider"></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 min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" id="code_version" name="branch_name">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branch_name }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{else}}
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branchName }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{end}}
</select>
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>

<div class="required inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" id="code_version" name="branch_name">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branch_name }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{else}}
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branchName }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{end}}
</select>
</div> </div>






<div class="required unite min_title inline fields" style="width: 90%;">
<label
style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<div class="required inline min_title fields" style="width: 95%;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}</label>
<div class="field" style="flex: 1.5;"> <div class="field" style="flex: 1.5;">
<select class="ui dropdown width" id="trainjob_engines"> <select class="ui dropdown width" id="trainjob_engines">
{{range .engines}} {{range .engines}}
@@ -176,44 +167,37 @@
</div> </div>


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


</div> </div>


</div> </div>


<div class="inline unite min_title field required">
<label 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">
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3"
autofocus required maxlength="255">
{{end}}
<span>
<i class="question circle icon link"
data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}}
data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example"
target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
<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}}" 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}}
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div> </div>
<div id="select-multi-dataset">


{{template "custom/select_dataset_train" .}}
<span class="tooltips"
style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span>
<div class="inline unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<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>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span>
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<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;"> <div class="dynamic field" style="margin-top: 1rem;">
{{if ne 0 (len .params)}} {{if ne 0 (len .params)}}
{{range $k ,$v := .params}} {{range $k ,$v := .params}}
@@ -235,7 +219,7 @@
</div> </div>




<div class="required field " style="display: none;">
<div class="required min_title field " style="display: none;">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> <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"> <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id">
{{range .resource_pools}} {{range .resource_pools}}
@@ -261,17 +245,16 @@
</div> </div>
</div> </div>


<div class="required unite min_title inline field" id="flaver_name">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor">
<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}} {{range .flavor_infos}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option> <option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{end}} {{end}}
</select> </select>
</div> </div>
<div class="inline required unite min_title field">
<label
style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<div class="inline required min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>


<div class="ui labeled input" style="width: 5%;"> <div class="ui labeled input" style="width: 5%;">


@@ -287,7 +270,8 @@
</div> </div>
</div> </div>


<div class="inline unite min_title field">
<div class="inline field" style="padding: 1rem 0;">
<label class="label-fix-width"></label>
<button class="ui create_train_job green button"> <button class="ui create_train_job green button">
{{.i18n.Tr "repo.cloudbrain.new"}} {{.i18n.Tr "repo.cloudbrain.new"}}
</button> </button>
@@ -310,7 +294,11 @@


$('.menu .item') $('.menu .item')
.tab(); .tab();

$(document).keydown(function(event){
switch(event.keyCode){
case 13:return false;
}
});
// let sever_num = $("#trainjob_work_server_num_select .text").text() //$('#trainjob_work_server_num') // let sever_num = $("#trainjob_work_server_num_select .text").text() //$('#trainjob_work_server_num')
// console.log("sever_num:",sever_num) // console.log("sever_num:",sever_num)
// $('.add').click(function(){ // $('.add').click(function(){


+ 3
- 3
templates/user/dashboard/feeds.tmpl View File

@@ -111,11 +111,11 @@
<span class="text truncate issue title">{{index .GetIssueInfos 1 | RenderEmoji}}</span> <span class="text truncate issue title">{{index .GetIssueInfos 1 | RenderEmoji}}</span>
{{else if or (eq .GetOpType 10) (eq .GetOpType 21) (eq .GetOpType 22) (eq .GetOpType 23)}} {{else if or (eq .GetOpType 10) (eq .GetOpType 21) (eq .GetOpType 22) (eq .GetOpType 23)}}
<a href="{{.GetCommentLink}}" class="text truncate issue title">{{.GetIssueTitle | RenderEmoji}}</a> <a href="{{.GetCommentLink}}" class="text truncate issue title">{{.GetIssueTitle | RenderEmoji}}</a>
<p class="text light grey">{{index .GetIssueInfos 1 | RenderEmoji}}</p>
<p class="text truncate pre-wrap light grey">{{index .GetIssueInfos 1 | RenderEmoji}}</p>
{{else if eq .GetOpType 11}} {{else if eq .GetOpType 11}}
<p class="text light grey">{{index .GetIssueInfos 1}}</p>
<p class="text truncate pre-wrap light grey">{{index .GetIssueInfos 1}}</p>
{{else if or (eq .GetOpType 12) (eq .GetOpType 13) (eq .GetOpType 14) (eq .GetOpType 15)}} {{else if or (eq .GetOpType 12) (eq .GetOpType 13) (eq .GetOpType 14) (eq .GetOpType 15)}}
<span class="text truncate issue title">{{.GetIssueTitle | RenderEmoji}}</span>
<span class="text truncate pre-wrap issue title">{{.GetIssueTitle | RenderEmoji}}</span>
{{end}} {{end}}
<p class="text italic light grey">{{TimeSince .GetCreate $.i18n.Lang}}</p> <p class="text italic light grey">{{TimeSince .GetCreate $.i18n.Lang}}</p>
</div> </div>


+ 1155
- 0
web_src/js/components/dataset/selectDataset.vue
File diff suppressed because it is too large
View File


+ 283
- 207
web_src/js/components/images/selectGrampusImages.vue View File

@@ -1,216 +1,292 @@
<template> <template>

<div class="inline required field" :class="{ 'unite': benchmarkNew, 'min_title': benchmarkNew}">
<label v-if="benchmarkNew" style="font-weight: normal;">镜像</label>
<label v-else>镜像</label>
<span v-if="benchmarkNew">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<input v-if="benchmarkNew" type="text" name="image" :value="imageAddress" style="width: 48.5%;"
placeholder="选择镜像或输入镜像地址">
<input v-else type="text" name="image" :value="imageAddress" placeholder="选择镜像或输入镜像地址">
<el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;">选择镜像
</el-button>
<el-dialog title="选择镜像" :visible.sync="dialogVisible" width="50%">
<div class="ui icon input" style="z-index: 9999;position: absolute;right: 50px;height:30px;">
<i class="search icon" style="cursor: pointer;pointer-events:auto"></i>
<input type="text" placeholder="搜镜像Tag/描述/标签..." v-model="search">
<div
class="inline required field"
:class="{ unite: benchmarkNew, min_title: benchmarkNew }"
>
<label
v-if="benchmarkNew"
class="label-fix-width"
style="font-weight: normal"
>镜像</label
>
<label v-else>镜像</label>
<input
v-if="benchmarkNew"
type="text"
name="image"
:value="imageAddress"
style="width: 48.5%"
placeholder="选择镜像或输入镜像地址"
/>
<input
v-else
type="text"
name="image"
:value="imageAddress"
placeholder="选择镜像或输入镜像地址"
/>
<el-button
type="text"
@click="dialogVisible = true"
icon="el-icon-plus"
style="color: #0366d6"
>选择镜像
</el-button>
<el-dialog title="选择镜像" :visible.sync="dialogVisible" width="50%">
<div
class="ui icon input"
style="z-index: 9999; position: absolute; right: 50px; height: 30px"
>
<i
class="search icon"
style="cursor: pointer; pointer-events: auto"
></i>
<input
type="text"
placeholder="搜镜像Tag/描述/标签..."
v-model="search"
/>
</div>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 0;
border-bottom: 1px solid #f5f5f5;
"
v-for="(publicData, index) in tableDataPublic"
:key="index"
>
<div style="width: 90%">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<div style="display: flex; align-items: center">
<span
class="panel_dataset_name text-over"
style="margin-left: 0"
>{{ publicData.tag }}
</span>
<img
v-if="publicData.type == 5"
src="/img/jian.svg"
style="margin-left: 0.5rem"
/>
</div>

<div v-if="!!publicData.topics" class="text-over">
<span
v-for="(topic, index) in publicData.topics"
class="ui repo-topic label topic"
>{{ topic }}</span
>
</div>
</div>
<div style="margin-top: 8px; display: flex">
<a
v-if="publicData.relAvatarLink || publicData.userName"
:title="publicData.userName"
style="cursor: default"
>
<img
class="ui avatar mini image"
style="width: 20px; height: 20px"
:src="publicData.relAvatarLink"
/>
</a>
<a v-else
><img
class="ui avatar mini image"
title="Ghost"
src="/user/avatar/ghost/-1"
style="width: 20px; height: 20px"
/></a>
<span class="panel_datset_desc">{{
publicData.description
}}</span>
</div>
</div> </div>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic">
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5"
v-for="(publicData,index) in tableDataPublic" :key="index">
<div style="width: 90%;">
<div style="display: flex;align-items: center;justify-content: space-between;">
<div style="display: flex;align-items: center;">
<span class="panel_dataset_name text-over"
style="margin-left: 0;">{{publicData.tag}} </span>
<img v-if="publicData.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;">
</div>

<div v-if="!!publicData.topics" class="text-over">
<span v-for="(topic,index) in publicData.topics"
class="ui repo-topic label topic">{{topic}}</span>
</div>
</div>
<div style="margin-top: 8px;display: flex;">
<a v-if="publicData.relAvatarLink||publicData.userName" :title="publicData.userName"
style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;"
:src="publicData.relAvatarLink">
</a>
<a v-else><img class="ui avatar mini image" title="Ghost" src="/user/avatar/ghost/-1"
style="width: 20px;height: 20px;"></a>
<span class="panel_datset_desc">{{publicData.description}}</span>
</div>
</div>
<div>
<button class="ui primary basic button mini"
@click.stop.prevent="selectImages(publicData.place,publicData.tag)">使用</button>
</div>
</div>
<div class="ui container" style="margin-top:50px;text-align:center">
<el-pagination background @current-change="handleCurrentChangePublic"
:current-page="currentPagePublic" :page-size="pageSizePublic"
layout="total, prev, pager, next" :total="totalNumPublic">
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>



<div>
<button
class="ui primary basic button mini"
@click.stop.prevent="
selectImages(publicData.place, publicData.tag)
"
>
使用
</button>
</div>
</div>
<div
class="ui container"
style="margin-top: 50px; text-align: center"
>
<el-pagination
background
@current-change="handleCurrentChangePublic"
:current-page="currentPagePublic"
:page-size="pageSizePublic"
layout="total, prev, pager, next"
:total="totalNumPublic"
>
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</template> </template>


<script> <script>

const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config;




export default {
components: {

},
data() {
return {
dialogVisible: false,
benchmarkNew: false,
imageAddress: '',
activeName: 'first',
search: '',
checked: false,
currentPagePublic: 1,
pageSizePublic: 5,
totalNumPublic: 0,
paramsPublic: { page: 1, pageSize: 5, q: '', recommend: false,cloudbrainType: 2 },
tableDataPublic: [],
loadingPublic: false,

};
},
methods: {
handleClick(tab, event) {
this.search = ''
if (tab.name == "first") {
this.paramsPublic.q = ''
this.getImageListPublic()
}

},
tableHeaderStyle({ row, column, rowIndex, columnIndex }) {

if (rowIndex === 0) {
return 'background:#f5f5f6;color:#606266'
}

},

handleCurrentChangePublic(val) {
this.paramsPublic.page = val
this.getImageListPublic()

},

getImageListPublic() {
this.loadingPublic = true
this.$axios.get('/explore/images/public', {
params: this.paramsPublic
}).then((res) => {
this.totalNumPublic = res.data.count
this.tableDataPublic = res.data.images
this.loadingPublic = false
})
},

searchName() {
if (this.activeName == 'first') {
this.paramsPublic.q = this.search
this.paramsPublic.page = 1
this.getImageListPublic()
}

},

selectImages(place) {
this.imageAddress = place
this.dialogVisible = false
},

},
watch: {
search(val) {
if (this.activeName == 'first') {
this.paramsPublic.q = val
this.getImageListPublic()
}
}

},
mounted() {
this.getImageListPublic()
if (location.href.indexOf('benchmark') !== -1 || location.href.indexOf('train-job') !== -1) {
this.benchmarkNew = true
}
},
created() {

}

const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config;

export default {
components: {},
data() {
return {
dialogVisible: false,
benchmarkNew: false,
imageAddress: "",
activeName: "first",
search: "",
checked: false,
currentPagePublic: 1,
pageSizePublic: 5,
totalNumPublic: 0,
paramsPublic: {
page: 1,
pageSize: 5,
q: "",
recommend: false,
cloudbrainType: 2,
},
tableDataPublic: [],
loadingPublic: false,
}; };
},
methods: {
handleClick(tab, event) {
this.search = "";
if (tab.name == "first") {
this.paramsPublic.q = "";
this.getImageListPublic();
}
},
tableHeaderStyle({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0) {
return "background:#f5f5f6;color:#606266";
}
},

handleCurrentChangePublic(val) {
this.paramsPublic.page = val;
this.getImageListPublic();
},

getImageListPublic() {
this.loadingPublic = true;
this.$axios
.get("/explore/images/public", {
params: this.paramsPublic,
})
.then((res) => {
this.totalNumPublic = res.data.count;
this.tableDataPublic = res.data.images;
this.loadingPublic = false;
});
},

searchName() {
if (this.activeName == "first") {
this.paramsPublic.q = this.search;
this.paramsPublic.page = 1;
this.getImageListPublic();
}
},

selectImages(place) {
this.imageAddress = place;
this.dialogVisible = false;
},
},
watch: {
search(val) {
if (this.activeName == "first") {
this.paramsPublic.q = val;
this.getImageListPublic();
}
},
},
mounted() {
this.getImageListPublic();
if (
location.href.indexOf("benchmark") !== -1 ||
location.href.indexOf("train-job") !== -1
) {
this.benchmarkNew = true;
}
},
created() {},
};
</script> </script>


<style scoped> <style scoped>
.header-wrapper {
background-color: #f5f5f6;
padding-top: 15px;
}

.image_text {
padding: 25px 0 55px 0;
}

#header {
position: relative;
top: -40px;
}

#success {
background-color: #5bb973;
color: white;
}

.text-over {
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
}

.image_title {
display: inline-block;
width: 80%;
cursor: default;
color: rgb(66, 98, 144);
}

.image_desc {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
}

.heart-stroke {
stroke: #666;
stroke-width: 2;
fill: #fff
}

.stars_active {
fill: #FA8C16 !important;
stroke: #FA8C16 !important
}
</style>
.header-wrapper {
background-color: #f5f5f6;
padding-top: 15px;
}
.image_text {
padding: 25px 0 55px 0;
}
#header {
position: relative;
top: -40px;
}
#success {
background-color: #5bb973;
color: white;
}
.text-over {
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
}
.image_title {
display: inline-block;
width: 80%;
cursor: default;
color: rgb(66, 98, 144);
}
.image_desc {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
}
.heart-stroke {
stroke: #666;
stroke-width: 2;
fill: #fff;
}
.stars_active {
fill: #fa8c16 !important;
stroke: #fa8c16 !important;
}
</style>

+ 560
- 367
web_src/js/components/images/selectImages.vue View File

@@ -1,376 +1,569 @@
<template> <template>

<div class="inline required field" :class="{ 'unite': benchmarkNew, 'min_title': benchmarkNew}">
<label v-if="benchmarkNew" style="font-weight: normal;">镜像</label>
<label v-else>镜像</label>
<span v-if="benchmarkNew">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<input v-if="benchmarkNew" type="text" name="image" :value="imageAddress" style="width: 48.5%;"
placeholder="选择镜像或输入镜像地址" required>
<input v-else type="text" name="image" :value="imageAddress" placeholder="选择镜像或输入镜像地址" required>
<el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;">选择镜像
</el-button>
<el-dialog title="选择镜像" :visible.sync="dialogVisible" width="50%">
<div class="ui icon input" style="z-index: 9999;position: absolute;right: 50px;height:30px;">
<i class="search icon" style="cursor: pointer;pointer-events:auto"></i>
<input type="text" placeholder="搜镜像Tag/描述/标签..." v-model="search">
<div
class="inline required field"
:class="{ min_title: benchmarkNew, unite: benchmark }"
>
<label
v-if="benchmarkNew"
class="label-fix-width"
style="font-weight: normal"
>镜像</label
>
<label v-else>镜像</label>
<span v-if="benchmark">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<input
v-if="benchmarkNew"
type="text"
name="image"
:value="imageAddress"
style="width: 48.5%"
placeholder="选择镜像或输入镜像地址"
required
/>
<input
v-else
type="text"
name="image"
:value="imageAddress"
placeholder="选择镜像或输入镜像地址"
required
/>
<el-button
type="text"
@click="dialogVisible = true"
icon="el-icon-plus"
style="color: #0366d6"
>选择镜像
</el-button>
<el-dialog title="选择镜像" :visible.sync="dialogVisible" width="50%">
<div
class="ui icon input"
style="z-index: 9999; position: absolute; right: 50px; height: 30px"
>
<i
class="search icon"
style="cursor: pointer; pointer-events: auto"
></i>
<input
type="text"
placeholder="搜镜像Tag/描述/标签..."
v-model="search"
/>
</div>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 0;
border-bottom: 1px solid #f5f5f5;
"
v-for="(publicData, index) in tableDataPublic"
:key="index"
>
<div style="width: 90%">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<div style="display: flex; align-items: center">
<span
class="panel_dataset_name text-over"
style="margin-left: 0"
>{{ publicData.tag }}
</span>
<img
v-if="publicData.type == 5"
src="/img/jian.svg"
style="margin-left: 0.5rem"
/>
</div>

<div v-if="!!publicData.topics" class="text-over">
<span
v-for="(topic, index) in publicData.topics"
class="ui repo-topic label topic"
>{{ topic }}</span
>
</div>
</div>
<div style="margin-top: 8px; display: flex">
<a
v-if="publicData.relAvatarLink || publicData.userName"
:title="publicData.userName"
style="cursor: default"
>
<img
class="ui avatar mini image"
style="width: 20px; height: 20px"
:src="publicData.relAvatarLink"
/>
</a>
<a v-else
><img
class="ui avatar mini image"
title="Ghost"
src="/user/avatar/ghost/-1"
style="width: 20px; height: 20px"
/></a>
<span class="panel_datset_desc">{{
publicData.description
}}</span>
</div>
</div> </div>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic">
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5"
v-for="(publicData,index) in tableDataPublic" :key="index">
<div style="width: 90%;">
<div style="display: flex;align-items: center;justify-content: space-between;">
<div style="display: flex;align-items: center;">
<span class="panel_dataset_name text-over"
style="margin-left: 0;">{{publicData.tag}} </span>
<img v-if="publicData.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;">
</div>

<div v-if="!!publicData.topics" class="text-over">
<span v-for="(topic,index) in publicData.topics"
class="ui repo-topic label topic">{{topic}}</span>
</div>
</div>
<div style="margin-top: 8px;display: flex;">
<a v-if="publicData.relAvatarLink||publicData.userName" :title="publicData.userName"
style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;"
:src="publicData.relAvatarLink">
</a>
<a v-else><img class="ui avatar mini image" title="Ghost" src="/user/avatar/ghost/-1"
style="width: 20px;height: 20px;"></a>
<span class="panel_datset_desc">{{publicData.description}}</span>
</div>
</div>
<div>
<button class="ui primary basic button mini"
@click.stop.prevent="selectImages(publicData.place,publicData.tag)">使用</button>
</div>
</div>
<div class="ui container" style="margin-top:50px;text-align:center">
<el-pagination background @current-change="handleCurrentChangePublic"
:current-page="currentPagePublic" :page-size="pageSizePublic"
layout="total, prev, pager, next" :total="totalNumPublic">
</el-pagination>
</div>
</el-tab-pane>

<el-tab-pane label="我的镜像" name="second" v-loading="loadingCustom">
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5"
v-for="(customData,index) in tableDataCustom" :key="index">
<div style="width: 90%;">
<div style="display: flex;align-items: center;justify-content: space-between;">
<span class="panel_dataset_name text-over" style="margin-left: 0;">{{customData.tag}}
</span>
<div v-if="!!customData.topics" class="text-over">
<span v-for="(topic,index) in customData.topics"
class="ui repo-topic label topic">{{topic}}</span>
</div>
</div>
<div style="margin-top: 8px;display: flex;">
<a v-if="customData.relAvatarLink||customData.userName" :title="customData.userName"
style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;"
:src="customData.relAvatarLink">
</a>
<a v-else><img class="ui avatar mini image" title="Ghost" src="/user/avatar/ghost/-1"
style="width: 20px;height: 20px;"></a>

<span class="panel_datset_desc">{{customData.description}}</span>
</div>
</div>
<div>
<button v-if="customData.status===1" class="ui primary basic button mini"
@click.stop.prevent="selectImages(customData.place,customData.tag)">使用</button>
<span v-if="customData.status===0" style="display: flex;align-items: center;">
<i class="CREATING"></i>
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;">提交中</span>
</span>
<span v-if="customData.status===2" style="display: flex;align-items: center;">
<i class="FAILED"></i>
<el-tooltip class="item" effect="dark" content="检测提交镜像是否大小超过20G!" placement="left">
<span style="margin-left: 0.4em;font-size: 12px;color:red;">提交失败</span>
</el-tooltip>

</span>
</div>
</div>
<div class="ui container" style="margin-top:50px;text-align:center">
<el-pagination background @current-change="handleCurrentChangeCustom"
:current-page="currentPageCustom" :page-size="pageSizeCustom"
layout="total, prev, pager, next" :total="totalNumCustom">
</el-pagination>
</div>
</el-tab-pane>

<el-tab-pane label="我收藏的镜像" name="third">
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5"
v-for="(starData,index) in tableDataStar" :key="index">
<div style="width: 90%;">
<div style="display: flex;align-items: center;justify-content: space-between;">
<div style="display: flex;align-items: center;">
<span class="panel_dataset_name text-over" style="margin-left: 0;">{{starData.tag}}
</span>
<img v-if="starData.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;">
</div>

<div v-if="!!starData.topics" class="text-over">
<span v-for="(topic,index) in starData.topics"
class="ui repo-topic label topic">{{topic}}</span>
</div>
</div>
<div style="margin-top: 8px;display: flex;">
<a v-if="starData.relAvatarLink||starData.userName" :title="starData.userName"
style="cursor: default;">
<img class="ui avatar mini image" style="width: 20px;height: 20px;"
:src="starData.relAvatarLink">
</a>
<a v-else><img class="ui avatar mini image" title="Ghost" src="/user/avatar/ghost/-1"
style="width: 20px;height: 20px;"></a>
<span class="panel_datset_desc">{{starData.description}}</span>
</div>
</div>
<div>
<button class="ui primary basic button mini"
@click.stop.prevent="selectImages(starData.place,starData.tag)">使用</button>
</div>
</div>
<div class="ui container" style="margin-top:50px;text-align:center">
<el-pagination background @current-change="handleCurrentChangeStar"
:current-page="currentPageStar" :page-size="pageSizeStar" layout="total, prev, pager, next"
:total="totalNumStar">
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>



<div>
<button
class="ui primary basic button mini"
@click.stop.prevent="
selectImages(publicData.place, publicData.tag)
"
>
使用
</button>
</div>
</div>
<div
class="ui container"
style="margin-top: 50px; text-align: center"
>
<el-pagination
background
@current-change="handleCurrentChangePublic"
:current-page="currentPagePublic"
:page-size="pageSizePublic"
layout="total, prev, pager, next"
:total="totalNumPublic"
>
</el-pagination>
</div>
</el-tab-pane>

<el-tab-pane label="我的镜像" name="second" v-loading="loadingCustom">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 0;
border-bottom: 1px solid #f5f5f5;
"
v-for="(customData, index) in tableDataCustom"
:key="index"
>
<div style="width: 90%">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<span
class="panel_dataset_name text-over"
style="margin-left: 0"
>{{ customData.tag }}
</span>
<div v-if="!!customData.topics" class="text-over">
<span
v-for="(topic, index) in customData.topics"
class="ui repo-topic label topic"
>{{ topic }}</span
>
</div>
</div>
<div style="margin-top: 8px; display: flex">
<a
v-if="customData.relAvatarLink || customData.userName"
:title="customData.userName"
style="cursor: default"
>
<img
class="ui avatar mini image"
style="width: 20px; height: 20px"
:src="customData.relAvatarLink"
/>
</a>
<a v-else
><img
class="ui avatar mini image"
title="Ghost"
src="/user/avatar/ghost/-1"
style="width: 20px; height: 20px"
/></a>

<span class="panel_datset_desc">{{
customData.description
}}</span>
</div>
</div>
<div>
<button
v-if="customData.status === 1"
class="ui primary basic button mini"
@click.stop.prevent="
selectImages(customData.place, customData.tag)
"
>
使用
</button>
<span
v-if="customData.status === 0"
style="display: flex; align-items: center"
>
<i class="CREATING"></i>
<span
style="margin-left: 0.4em; font-size: 12px; color: #5a5a5a"
>提交中</span
>
</span>
<span
v-if="customData.status === 2"
style="display: flex; align-items: center"
>
<i class="FAILED"></i>
<el-tooltip
class="item"
effect="dark"
content="检测提交镜像是否大小超过20G!"
placement="left"
>
<span style="margin-left: 0.4em; font-size: 12px; color: red"
>提交失败</span
>
</el-tooltip>
</span>
</div>
</div>
<div
class="ui container"
style="margin-top: 50px; text-align: center"
>
<el-pagination
background
@current-change="handleCurrentChangeCustom"
:current-page="currentPageCustom"
:page-size="pageSizeCustom"
layout="total, prev, pager, next"
:total="totalNumCustom"
>
</el-pagination>
</div>
</el-tab-pane>

<el-tab-pane label="我收藏的镜像" name="third">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 0;
border-bottom: 1px solid #f5f5f5;
"
v-for="(starData, index) in tableDataStar"
:key="index"
>
<div style="width: 90%">
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<div style="display: flex; align-items: center">
<span
class="panel_dataset_name text-over"
style="margin-left: 0"
>{{ starData.tag }}
</span>
<img
v-if="starData.type == 5"
src="/img/jian.svg"
style="margin-left: 0.5rem"
/>
</div>

<div v-if="!!starData.topics" class="text-over">
<span
v-for="(topic, index) in starData.topics"
class="ui repo-topic label topic"
>{{ topic }}</span
>
</div>
</div>
<div style="margin-top: 8px; display: flex">
<a
v-if="starData.relAvatarLink || starData.userName"
:title="starData.userName"
style="cursor: default"
>
<img
class="ui avatar mini image"
style="width: 20px; height: 20px"
:src="starData.relAvatarLink"
/>
</a>
<a v-else
><img
class="ui avatar mini image"
title="Ghost"
src="/user/avatar/ghost/-1"
style="width: 20px; height: 20px"
/></a>
<span class="panel_datset_desc">{{
starData.description
}}</span>
</div>
</div>
<div>
<button
class="ui primary basic button mini"
@click.stop.prevent="selectImages(starData.place, starData.tag)"
>
使用
</button>
</div>
</div>
<div
class="ui container"
style="margin-top: 50px; text-align: center"
>
<el-pagination
background
@current-change="handleCurrentChangeStar"
:current-page="currentPageStar"
:page-size="pageSizeStar"
layout="total, prev, pager, next"
:total="totalNumStar"
>
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</template> </template>


<script> <script>

const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config;




export default {
components: {

},
data() {
return {
dialogVisible: false,
benchmarkNew: false,
imageAddress: '',
activeName: 'first',
search: '',
checked: false,
currentPagePublic: 1,
pageSizePublic: 5,
totalNumPublic: 0,
paramsPublic: { page: 1, pageSize: 5, q: '', recommend: false },
tableDataPublic: [],
loadingPublic: false,

currentPageCustom: 1,
pageSizeCustom: 5,
totalNumCustom: 0,
paramsCustom: { page: 1, pageSize: 5, q: '' },
tableDataCustom: [],
starCustom: [],
loadingCustom: false,

currentPageStar: 1,
pageSizeStar: 5,
totalNumStar: 0,
paramsStar: { page: 1, pageSize: 5, q: '' },
tableDataStar: [],
loadingStar: false
};
},
methods: {
handleClick(tab, event) {
this.search = ''
if (tab.name == "first") {
this.paramsPublic.q = ''
this.getImageListPublic()
}
if (tab.name == "second") {
this.getImageListCustom()
}
if (tab.name == "third") {
this.getImageListStar()
}

},
tableHeaderStyle({ row, column, rowIndex, columnIndex }) {

if (rowIndex === 0) {
return 'background:#f5f5f6;color:#606266'
}

},

handleCurrentChangePublic(val) {
this.paramsPublic.page = val
this.getImageListPublic()

},

handleCurrentChangeCustom(val) {
this.paramsCustom.page = val
this.getImageListCustom()

},
handleCurrentChangeStar(val) {
this.paramsStar.page = val
this.getImageListStar()

},
getImageListPublic() {
this.loadingPublic = true
this.$axios.get('/explore/images/public', {
params: this.paramsPublic
}).then((res) => {
this.totalNumPublic = res.data.count
this.tableDataPublic = res.data.images
this.loadingPublic = false
})
},

getImageListCustom() {
this.loadingCustom = true
this.$axios.get('/explore/images/custom', {
params: this.paramsCustom
}).then((res) => {
this.totalNumCustom = res.data.count
this.tableDataCustom = res.data.images
this.tableDataCustom.forEach(element => {
this.starCustom.push({ id: element.id, })

});
this.loadingCustom = false
})
},

getImageListStar() {
this.loadingStar = true
this.$axios.get('/explore/images/star', {
params: this.paramsStar
}).then((res) => {
this.totalNumStar = res.data.count
this.tableDataStar = res.data.images
this.loadingStar = false
})
},
searchName() {
if (this.activeName == 'first') {
this.paramsPublic.q = this.search
this.paramsPublic.page = 1
this.getImageListPublic()
}
if (this.activeName == 'second') {
this.paramsCustom.q = this.search
this.paramsCustom.page = 1
this.getImageListCustom()
}
if (this.activeName == 'third') {
this.paramsStar.q = this.search
this.paramsStar.page = 1
this.getImageListStar()
}

},
selectImages(place) {
this.imageAddress = place
this.dialogVisible = false
},

},
watch: {
search(val) {
if (this.activeName == 'first') {
this.paramsPublic.q = val
this.getImageListPublic()
}
if (this.activeName == 'second') {
this.paramsCustom.q = val
this.getImageListCustom()
}
if (this.activeName == 'third') {
this.paramsStar.q = val
this.getImageListStar()
}
}

},
mounted() {
this.getImageListPublic()
if (location.href.indexOf('benchmark') !== -1 || location.href.indexOf('train-job') !== -1) {
this.benchmarkNew = true
}
},
created() {

}

const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config;

export default {
components: {},
data() {
return {
dialogVisible: false,
benchmarkNew: false,
benchmark: false,
imageAddress: "",
activeName: "first",
search: "",
checked: false,
currentPagePublic: 1,
pageSizePublic: 5,
totalNumPublic: 0,
paramsPublic: { page: 1, pageSize: 5, q: "", recommend: false },
tableDataPublic: [],
loadingPublic: false,

currentPageCustom: 1,
pageSizeCustom: 5,
totalNumCustom: 0,
paramsCustom: { page: 1, pageSize: 5, q: "" },
tableDataCustom: [],
starCustom: [],
loadingCustom: false,

currentPageStar: 1,
pageSizeStar: 5,
totalNumStar: 0,
paramsStar: { page: 1, pageSize: 5, q: "" },
tableDataStar: [],
loadingStar: false,
}; };
</script>

<style scoped>
.header-wrapper {
background-color: #f5f5f6;
padding-top: 15px;
},
methods: {
handleClick(tab, event) {
this.search = "";
if (tab.name == "first") {
this.paramsPublic.q = "";
this.getImageListPublic();
}
if (tab.name == "second") {
this.getImageListCustom();
}
if (tab.name == "third") {
this.getImageListStar();
}
},
tableHeaderStyle({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0) {
return "background:#f5f5f6;color:#606266";
}
},

handleCurrentChangePublic(val) {
this.paramsPublic.page = val;
this.getImageListPublic();
},

handleCurrentChangeCustom(val) {
this.paramsCustom.page = val;
this.getImageListCustom();
},
handleCurrentChangeStar(val) {
this.paramsStar.page = val;
this.getImageListStar();
},
getImageListPublic() {
this.loadingPublic = true;
this.$axios
.get("/explore/images/public", {
params: this.paramsPublic,
})
.then((res) => {
this.totalNumPublic = res.data.count;
this.tableDataPublic = res.data.images;
this.loadingPublic = false;
});
},

getImageListCustom() {
this.loadingCustom = true;
this.$axios
.get("/explore/images/custom", {
params: this.paramsCustom,
})
.then((res) => {
this.totalNumCustom = res.data.count;
this.tableDataCustom = res.data.images;
this.tableDataCustom.forEach((element) => {
this.starCustom.push({ id: element.id });
});
this.loadingCustom = false;
});
},

getImageListStar() {
this.loadingStar = true;
this.$axios
.get("/explore/images/star", {
params: this.paramsStar,
})
.then((res) => {
this.totalNumStar = res.data.count;
this.tableDataStar = res.data.images;
this.loadingStar = false;
});
},
searchName() {
if (this.activeName == "first") {
this.paramsPublic.q = this.search;
this.paramsPublic.page = 1;
this.getImageListPublic();
}
if (this.activeName == "second") {
this.paramsCustom.q = this.search;
this.paramsCustom.page = 1;
this.getImageListCustom();
}
if (this.activeName == "third") {
this.paramsStar.q = this.search;
this.paramsStar.page = 1;
this.getImageListStar();
}
},
selectImages(place) {
this.imageAddress = place;
this.dialogVisible = false;
},
},
watch: {
search(val) {
if (this.activeName == "first") {
this.paramsPublic.q = val;
this.getImageListPublic();
}
if (this.activeName == "second") {
this.paramsCustom.q = val;
this.getImageListCustom();
}
if (this.activeName == "third") {
this.paramsStar.q = val;
this.getImageListStar();
}
},
},
mounted() {
this.getImageListPublic();
if (
location.href.indexOf("train-job") !== -1 ||
location.href.indexOf("benchmark") !== -1
) {
this.benchmarkNew = true;
} }

.image_text {
padding: 25px 0 55px 0;
}

#header {
position: relative;
top: -40px;
}

#success {
background-color: #5bb973;
color: white;
}

.text-over {
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
}

.image_title {
display: inline-block;
width: 80%;
cursor: default;
color: rgb(66, 98, 144);
}

.image_desc {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
}

.heart-stroke {
stroke: #666;
stroke-width: 2;
fill: #fff
if (location.href.indexOf("cloudbrain/benchmark/") !== -1) {
this.benchmark = true;
} }
},
created() {},
};
</script>


.stars_active {
fill: #FA8C16 !important;
stroke: #FA8C16 !important
}
</style>
<style scoped>
.header-wrapper {
background-color: #f5f5f6;
padding-top: 15px;
}

.image_text {
padding: 25px 0 55px 0;
}

#header {
position: relative;
top: -40px;
}

#success {
background-color: #5bb973;
color: white;
}

.text-over {
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
}

.image_title {
display: inline-block;
width: 80%;
cursor: default;
color: rgb(66, 98, 144);
}

.image_desc {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
}

.heart-stroke {
stroke: #666;
stroke-width: 2;
fill: #fff;
}

.stars_active {
fill: #fa8c16 !important;
stroke: #fa8c16 !important;
}
</style>

+ 2095
- 2121
web_src/js/index.js
File diff suppressed because it is too large
View File


+ 3
- 0
web_src/less/_base.less View File

@@ -489,6 +489,9 @@ code,
white-space: nowrap; white-space: nowrap;
display: inline-block; display: inline-block;
} }
&.pre-wrap{
white-space:pre-wrap!important;
}


&.thin { &.thin {
font-weight: normal; font-weight: normal;


+ 849
- 728
web_src/less/openi.less
File diff suppressed because it is too large
View File


Loading…
Cancel
Save