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 {

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

uuidInCondition := "(" + strings.Join(uuidArray, ",") + ")"
// 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)
}

@@ -560,6 +567,35 @@ func GetAttachmentSizeByDatasetID(datasetID int64) (int64, error) {
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) {
return x.SumInt(&Attachment{}, "size")
}


+ 59
- 0
models/cloudbrain.go View File

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

import (
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
@@ -1023,6 +1024,16 @@ type Parameter struct {
type Parameters struct {
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 {
DatasetID string `json:"dataset_id"`
@@ -1979,3 +1990,51 @@ func CloudbrainAllStatic(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, er
}
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.
Where("id > 0").
In("id", keysInt64(userIdSet)).
Cols("id", "lower_name", "name", "full_name", "email").
Find(&users); err != nil {
return fmt.Errorf("find users: %v", err)
}
if err := e.
Where("id > 0").
In("id", keysInt64(set)).
Cols("id", "owner_id", "owner_name", "lower_name", "name", "description", "alias", "lower_alias","is_private").
Find(&repos); err != nil {
return fmt.Errorf("find repos: %v", err)
}
@@ -98,19 +100,81 @@ func (datasets DatasetList) loadAttributes(e Engine) error {
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 {
Keyword string
OwnerID int64
User *User
RepoID int64
IncludePublic bool
RecommendOnly bool
Category string
Task string
License string
DatasetIDs []int64
DatasetIDs []int64 // 目前只在StarByMe为true时起作用
ListOptions
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) {
@@ -159,30 +223,40 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond {
if opts.RepoID > 0 {
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{"attachment.is_private": false})
if opts.OwnerID > 0 {

subCon := builder.NewCond()
subCon = subCon.And(builder.Eq{"repository.owner_id": opts.OwnerID})
subCon = generateFilterCond(opts, 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})
if !opts.IsOwner {
cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic})
cond = cond.And(builder.Eq{"attachment.is_private": false})
}
}

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
@@ -208,6 +282,17 @@ func generateFilterCond(opts *SearchDatasetOptions, cond builder.Cond) builder.C
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
}

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

if opts.PageSize > 0 {
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)
}

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

return datasets, count, nil
}

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

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

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 {
if !ctx.IsSigned {
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 versionCount int
if jobType == string(models.JobTypeTrain) {

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

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

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 {
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()
jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName,
jobResult, err := CreateJob(req.JobName, models.CreateJobParams{
JobName: req.JobName,
RetryCount: 1,
GpuType: gpuQueue,
Image: image,
GpuType: req.GpuQueue,
Image: req.Image,
TaskRoles: []models.TaskRole{
{
Name: SubTaskName,
@@ -246,94 +315,51 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command,
GPUNumber: resourceSpec.GpuNum,
MemoryMB: resourceSpec.MemMiB,
ShmMB: resourceSpec.ShareMemMiB,
Command: command,
Command: req.Command,
NeedIBDevice: false,
IsMainRole: 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 {
log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
log.Error("CreateJob failed:", err.Error(), req.Ctx.Data["MsgID"])
return err
}
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)
}

var jobID = jobResult.Payload["jobId"].(string)
err = models.CreateCloudbrain(&models.Cloudbrain{
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,
JobName: jobName,
DisplayJobName: displayJobName,
JobName: req.JobName,
DisplayJobName: req.DisplayJobName,
SubTaskName: SubTaskName,
JobType: jobType,
JobType: req.JobType,
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,
BenchmarkTypeID: benchmarkTypeID,
BenchmarkChildTypeID: benchmarkChildTypeID,
Description: description,
BenchmarkTypeID: req.BenchmarkTypeID,
BenchmarkChildTypeID: req.BenchmarkChildTypeID,
Description: req.Description,
IsLatestVersion: "1",
VersionCount: versionCount,
BranchName: branchName,
BootFile: bootFile,
DatasetName: datasetName,
Parameters: params,
BranchName: req.BranchName,
BootFile: req.BootFile,
DatasetName: req.DatasetNames,
Parameters: req.Params,
CreatedUnix: createTime,
UpdatedUnix: createTime,
CommitID: commitID,
CommitID: req.CommitID,
})

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

task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
log.Error("GetCloudbrainByName failed: %v", err.Error())
log.Error("GetCloudbrainByJobID failed: %v", err.Error())
return err
}
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 {
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
@@ -363,11 +389,6 @@ func IsBenchmarkJob(jobType string) bool {
}

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

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

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()
jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName,
@@ -407,50 +492,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e
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 {
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,
Type: task.Type,
Uuid: task.Uuid,
DatasetName: task.DatasetName,
Image: task.Image,
GpuQueue: task.GpuQueue,
ResourceSpecId: task.ResourceSpecId,


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

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

type GenerateInferenceJobReq struct {
@@ -338,11 +340,6 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
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)
err = models.CreateCloudbrain(&models.Cloudbrain{
Status: TransTrainJobStatus(jobResult.Status),
@@ -356,7 +353,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
VersionID: jobResult.VersionID,
VersionName: jobResult.VersionName,
Uuid: req.Uuid,
DatasetName: attach.Name,
DatasetName: req.DatasetName,
CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion,
ComputeResource: models.NPUResource,
@@ -435,12 +432,6 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job
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
jobTypes = append(jobTypes, string(models.JobTypeTrain))
repo := ctx.Repo.Repository
@@ -468,7 +459,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job
VersionID: jobResult.VersionID,
VersionName: jobResult.VersionName,
Uuid: req.Uuid,
DatasetName: attach.Name,
DatasetName: req.DatasetName,
CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion,
PreVersionName: req.PreVersionName,


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

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

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

sec = Cfg.Section("benchmark")
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_stared=Unzipping
unzip_status=Unzip Status
collection_num=Collection Nums
[repo]
owner = Owner
repo_name = Repository Name
@@ -3081,3 +3082,5 @@ TRAIN = TRAIN
INFERENCE = INFERENCE
BENCHMARK = BENCHMARK
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_stared=解压中
unzip_status=解压状态
collection_num=收藏数量
[repo]
owner=拥有者
repo_name=项目名称
@@ -1477,7 +1477,7 @@ issues.filter_sort.mostforks=派生由多到少
issues.filter_sort.fewestforks=派生由少到多
issues.filter_sort.downloadtimes=下载次数
issues.filter_sort.citations=引用次数
issues.filter_sort.moststars=收藏数量
issues.filter_sort.moststars=点赞由多到少
issues.filter_sort.mostusecount=最多引用
issues.filter_sort.fewestusecount=最少引用

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

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

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

@@ -77,9 +77,10 @@ func Datasets(ctx *context.Context) {
Page: page,
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 {
ctx.ServerError("SearchDataset", err)


+ 10
- 9
routers/home.go View File

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

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{
Page: page,
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
jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
image := strings.TrimSpace(form.Image)
uuid := form.Attachment
uuids := form.Attachment
jobType := form.JobType
gpuQueue := form.GpuType
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath
resourceSpecId := form.ResourceSpecId
branchName := form.BranchName
repo := ctx.Repo.Repository

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)
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 == "" {
branchName = cloudbrain.DefaultBranchName
}
@@ -286,11 +294,33 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {

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 {
cloudBrainNewDataPrepare(ctx)
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["jobName"] = task.JobName
@@ -2011,11 +2035,42 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo
//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 {
cloudBrainNewDataPrepare(ctx)
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))
}

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 {
cloudBrainNewDataPrepare(ctx)
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) {
page := ctx.QueryInt("page")
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
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 {
log.Error("Failed to generateCommand: %s (%v)", displayJobName, err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
@@ -672,10 +672,10 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo
command += "pwd;cd " + workDir + grampus.CommandPrepareScript
//download code & dataset
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
} 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
}

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

//unzip code & dataset
toolUnzip := "unzip -q "
toolUnzip := "unzip -q '"
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

//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 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)
@@ -324,7 +347,7 @@ func NotebookShow(ctx *context.Context) {
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration)
}
ctx.Data["duration"] = task.TrainJobDuration
ctx.Data["datasetDownloadLink"] = datasetDownloadLink
ctx.Data["datasetDownload"] = datasetDownload
ctx.Data["task"] = task
ctx.Data["ID"] = ID
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
outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + 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
isLatestVersion := modelarts.IsLatestVersion
FlavorName := form.FlavorName
@@ -1078,6 +1101,27 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
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
if isSaveParam == "on" {
@@ -1144,6 +1188,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
EngineName: EngineName,
VersionCount: VersionCount,
TotalVersionCount: modelarts.TotalVersionCount,
DatasetName: datasetNames,
}

//将params转换Parameters.Parameter,出错时返回给前端
@@ -1205,7 +1250,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath + VersionOutputPath + "/"
outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + 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
PreVersionName := form.VersionName
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
if isSaveParam == "on" {
saveparams := append(param, models.Parameter{
@@ -1369,6 +1436,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
EngineName: EngineName,
PreVersionName: PreVersionName,
TotalVersionCount: latestTask.TotalVersionCount + 1,
DatasetName: datasetNames,
}

err = modelarts.GenerateTrainJobVersion(ctx, req, jobID)
@@ -2414,3 +2482,50 @@ func TrainJobDownloadLogFile(ctx *context.Context) {
ctx.Resp.Header().Set("Cache-Control", "max-age=0")
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("/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.Get("/:uuid", repo.GetDatasetStatus)
})


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

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

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}}"
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)}}
<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}}
{{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}}
<input type="hidden" name="attachment" :value="dataset_uuid">
<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"
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"
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"
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>


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

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

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


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

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

</style>

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

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

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

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


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


</script>

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

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


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

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

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

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

}

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

.width85 {
width: 85% !important;
margin-left: 4.5rem !important;
margin-left: 10.5rem !important;
align-items: center;
}
.width81 {
margin-left: 1.5rem !important;
width: 81% !important;
@@ -60,6 +55,14 @@
text-align: center;
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>
<!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div>
@@ -76,6 +79,7 @@
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
{{template "base/alert" .}}
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new"}}
@@ -87,22 +91,22 @@
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flaver_name" name="flaver_names" value="">
<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">
<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">
<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>
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}}
</a>
<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>
</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">
<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"
@@ -123,18 +127,18 @@
Ascend NPU</a>
</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">
<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 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"
placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}
onchange="this.value=this.value.substring(0, 255)"
@@ -143,11 +147,11 @@
</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">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
@@ -175,8 +179,8 @@
</select>
</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类型"
style='width:385px' name="gpu_type">
{{range .train_gpu_types}}
@@ -184,27 +188,12 @@
{{end}}
</select>
</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>

<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}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}"
tabindex="3" autofocus required maxlength="255">
@@ -219,13 +208,17 @@
</span>
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a>
</div>
<div id="select-multi-dataset">

</div>


{{template "custom/select_dataset_train" .}}
<!-- {{template "custom/select_dataset_train" .}} -->
<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"
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>
@@ -252,8 +245,8 @@
</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="选择资源规格"
style='width:385px' name="resource_spec_id">
{{range .train_resource_specs}}
@@ -263,7 +256,8 @@
</select>
</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">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
@@ -287,7 +281,11 @@

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

$(document).keydown(function(event){
switch(event.keyCode){
case 13:return false;
}
});
let sever_num = $('#trainjob_work_server_num')
$('.add').click(function () {
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" .}}
<style>

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

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

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

@@ -53,7 +48,13 @@
text-align: center;
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>
<!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div>
@@ -81,22 +82,22 @@
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flavor_name" name="flavor_name" value="">
<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">
<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>
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}}
</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>
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta)
</a>
</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">
<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">
@@ -113,23 +114,23 @@
Ascend NPU</a>
</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">
<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 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>
</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">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
@@ -152,8 +153,8 @@
<div id="images-new-grampus">
</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}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
@@ -168,8 +169,8 @@
{{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>
<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>
<input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;">
@@ -194,8 +195,8 @@
</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">
{{range .flavor_infos}}
<option name="flavor" value="{{.ID}}">{{.Name}}</option>
@@ -203,7 +204,8 @@
</select>
</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">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>


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

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

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

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

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

@@ -49,7 +43,13 @@
text-align: center;
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>
<!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div>
@@ -77,22 +77,22 @@
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_name" value="">
<input type="hidden" id="ai_flavor_name" name="flavor_name" value="">
<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">
<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>
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}}
</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>
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta)
</a>
</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">
<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">
@@ -109,23 +109,23 @@
Ascend NPU</a>
</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">
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span>
</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>
</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">
<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">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
@@ -145,8 +145,8 @@
</select>
</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">
{{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option>
@@ -154,8 +154,8 @@
</select>
</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}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
@@ -169,24 +169,24 @@
{{template "custom/select_dataset_train" .}}
<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>
<input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;">
</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">
{{range .flavor_infos}}
<option name="flavor" value="{{.ID}}">{{.Name}}</option>
{{end}}
</select>
</div>
<div class="inline required unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<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%;">

@@ -200,7 +200,8 @@
</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">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>


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

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

</div>

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


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

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

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

@@ -338,30 +337,6 @@
</div>
</td>
</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">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.description"}}
@@ -392,24 +367,6 @@
</div>
</td>
</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">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.train_job.standard"}}
@@ -456,6 +413,18 @@
</div>
</td>
</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>
@@ -463,8 +432,26 @@
</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>

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

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

@@ -1,59 +1,58 @@
{{template "base/head" .}}
<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;
color: rgba(16, 16, 16, 100) !important;
}

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

.min_title {
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>
<!-- <div class="ui page dimmer">
@@ -71,6 +70,7 @@
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
{{template "base/alert" .}}
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new"}}
@@ -82,9 +82,9 @@
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flaver_name" name="flaver_names" value="">
<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">
<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>
@@ -96,8 +96,8 @@
</a>
</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">
<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"
@@ -118,55 +118,46 @@
Ascend NPU</a>
</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 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 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 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;">
<select class="ui dropdown width" id="trainjob_engines">
{{range .engines}}
@@ -176,44 +167,37 @@
</div>

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

</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 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;">
{{if ne 0 (len .params)}}
{{range $k ,$v := .params}}
@@ -235,7 +219,7 @@
</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>
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id">
{{range .resource_pools}}
@@ -261,17 +245,16 @@
</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}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{end}}
</select>
</div>
<div class="inline required unite min_title field">
<label
style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<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%;">

@@ -287,7 +270,8 @@
</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">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
@@ -310,7 +294,11 @@

$('.menu .item')
.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')
// console.log("sever_num:",sever_num)
// $('.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>
{{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>
<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}}
<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)}}
<span class="text truncate issue title">{{.GetIssueTitle | RenderEmoji}}</span>
<span class="text truncate pre-wrap issue title">{{.GetIssueTitle | RenderEmoji}}</span>
{{end}}
<p class="text italic light grey">{{TimeSince .GetCreate $.i18n.Lang}}</p>
</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>

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

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

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

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

<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;
display: inline-block;
}
&.pre-wrap{
white-space:pre-wrap!important;
}

&.thin {
font-weight: normal;


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


Loading…
Cancel
Save