Browse Source

Merge pull request 'V20221228' (#3559) from V20221228 into develop

Reviewed-on: https://openi.pcl.ac.cn/OpenI/aiforge/pulls/3559
tags/v1.22.12.2
ychao_1983 2 years ago
parent
commit
7658370707
100 changed files with 2346 additions and 972 deletions
  1. +1
    -0
      .gitignore
  2. +1
    -0
      custom/public/css/placeholder-home.css
  3. +1
    -0
      custom/public/css/placeholder.css
  4. BIN
      custom/public/img/home-banner-02-1.jpg
  5. BIN
      custom/public/img/home-banner-02-2.png
  6. +45
    -0
      custom/public/img/logo-w-origin.svg
  7. +1
    -45
      custom/public/img/logo-w.svg
  8. +1
    -0
      custom/public/js/placeholder-home.js
  9. +1
    -0
      custom/public/js/placeholder.js
  10. +3
    -1
      models/action.go
  11. +6
    -0
      models/ai_model_manage.go
  12. +11
    -0
      models/attachment.go
  13. +113
    -47
      models/cloudbrain.go
  14. +10
    -1
      models/repo_statistic.go
  15. +1
    -0
      models/task_config.go
  16. +6
    -1
      models/user.go
  17. +24
    -0
      models/user_analysis_for_activity.go
  18. +176
    -45
      models/user_business_analysis.go
  19. +3
    -3
      models/user_business_struct.go
  20. +1
    -0
      modules/auth/modelarts.go
  21. +7
    -19
      modules/cloudbrain/cloudbrain.go
  22. +6
    -1
      modules/context/auth.go
  23. +7
    -5
      modules/convert/cloudbrain.go
  24. +65
    -10
      modules/grampus/grampus.go
  25. +0
    -1
      modules/grampus/resty.go
  26. +4
    -87
      modules/modelarts/modelarts.go
  27. +1
    -0
      modules/modelarts_cd/modelarts.go
  28. +198
    -0
      modules/notebook/contentManager.go
  29. +3
    -0
      modules/repository/repo.go
  30. +33
    -17
      modules/setting/setting.go
  31. +16
    -0
      modules/storage/minio_ext.go
  32. +33
    -4
      modules/storage/obs.go
  33. +28
    -27
      modules/structs/cloudbrain.go
  34. +10
    -2
      modules/templates/helper.go
  35. +28
    -4
      options/locale/locale_en-US.ini
  36. +30
    -6
      options/locale/locale_zh-CN.ini
  37. +34
    -65
      package-lock.json
  38. +8
    -5
      public/home/home.js
  39. BIN
      public/img/login_bg_default.png
  40. +1
    -1
      routers/admin/cloudbrains.go
  41. +5
    -1
      routers/api/v1/api.go
  42. +45
    -0
      routers/api/v1/repo/attachments.go
  43. +3
    -0
      routers/api/v1/repo/cloudbrain.go
  44. +48
    -18
      routers/api/v1/repo/cloudbrain_dashboard.go
  45. +32
    -0
      routers/api/v1/repo/modelmanage.go
  46. +8
    -6
      routers/api/v1/repo/repo_dashbord.go
  47. +20
    -0
      routers/api/v1/user/repo.go
  48. +4
    -0
      routers/home.go
  49. +21
    -14
      routers/repo/ai_model_manage.go
  50. +110
    -37
      routers/repo/cloudbrain.go
  51. +1
    -0
      routers/repo/dataset.go
  52. +78
    -8
      routers/repo/grampus.go
  53. +78
    -13
      routers/repo/modelarts.go
  54. +9
    -2
      routers/repo/repo_statistic.go
  55. +8
    -3
      routers/routes/routes.go
  56. +14
    -7
      routers/user/auth.go
  57. +1
    -1
      routers/user/home.go
  58. +14
    -14
      services/cloudbrain/clear.go
  59. +30
    -0
      services/cloudbrain/cloudbrainTask/ai_model.go
  60. +7
    -2
      services/cloudbrain/cloudbrainTask/count.go
  61. +269
    -29
      services/cloudbrain/cloudbrainTask/notebook.go
  62. +1
    -1
      services/socketwrap/clientManager.go
  63. +8
    -8
      templates/admin/cloudbrain/list.tmpl
  64. +2
    -0
      templates/admin/cloudbrain/search.tmpl
  65. +1
    -0
      templates/admin/cloudbrain/search_dashboard.tmpl
  66. +35
    -0
      templates/annual_privacy.tmpl
  67. +9
    -9
      templates/base/footer.tmpl
  68. +10
    -0
      templates/base/footer_content.tmpl
  69. +7
    -7
      templates/base/footer_fluid.tmpl
  70. +10
    -10
      templates/base/head.tmpl
  71. +10
    -10
      templates/base/head_course.tmpl
  72. +10
    -10
      templates/base/head_fluid.tmpl
  73. +14
    -14
      templates/base/head_home.tmpl
  74. +10
    -10
      templates/base/head_pro.tmpl
  75. +2
    -0
      templates/custom/header.tmpl
  76. +39
    -1
      templates/custom/home/home_top.tmpl
  77. +2
    -2
      templates/custom/task_wait_count.tmpl
  78. +1
    -0
      templates/explore/images.tmpl
  79. +4
    -4
      templates/explore/organizations.tmpl
  80. +2
    -2
      templates/explore/repo_orgtop.tmpl
  81. +1
    -1
      templates/explore/search_new.tmpl
  82. +3
    -1
      templates/home.tmpl
  83. +125
    -259
      templates/repo/cloudbrain/benchmark/new.tmpl
  84. +30
    -21
      templates/repo/cloudbrain/benchmark/show.tmpl
  85. +1
    -1
      templates/repo/cloudbrain/inference/new.tmpl
  86. +12
    -4
      templates/repo/cloudbrain/inference/show.tmpl
  87. +3
    -2
      templates/repo/cloudbrain/new.tmpl
  88. +3
    -0
      templates/repo/cloudbrain/show.tmpl
  89. +1
    -1
      templates/repo/cloudbrain/trainjob/new.tmpl
  90. +25
    -6
      templates/repo/cloudbrain/trainjob/show.tmpl
  91. +1
    -1
      templates/repo/datasets/dirs/dir_list.tmpl
  92. +1
    -1
      templates/repo/datasets/dirs/dir_preview.tmpl
  93. +1
    -1
      templates/repo/datasets/label/index.tmpl
  94. +1
    -0
      templates/repo/debugjob/index.tmpl
  95. +161
    -0
      templates/repo/grampus/notebook/gcu/new.tmpl
  96. +12
    -5
      templates/repo/grampus/notebook/gpu/new.tmpl
  97. +24
    -5
      templates/repo/grampus/notebook/npu/new.tmpl
  98. +26
    -7
      templates/repo/grampus/trainjob/show.tmpl
  99. +11
    -11
      templates/repo/header.tmpl
  100. +5
    -5
      templates/repo/home.tmpl

+ 1
- 0
.gitignore View File

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


+ 1
- 0
custom/public/css/placeholder-home.css View File

@@ -0,0 +1 @@
/* placeholder-home.css */

+ 1
- 0
custom/public/css/placeholder.css View File

@@ -0,0 +1 @@
/* placeholder.css */

BIN
custom/public/img/home-banner-02-1.jpg View File

Before After
Width: 1920  |  Height: 548  |  Size: 156 kB

BIN
custom/public/img/home-banner-02-2.png View File

Before After
Width: 790  |  Height: 315  |  Size: 253 kB

+ 45
- 0
custom/public/img/logo-w-origin.svg View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 160 64" style="enable-background:new 0 0 160 64;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{display:none;fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M105.3,33.3H87.1c-2.6,0.1-4,1.3-4,3.8v8.3c0.1,2.2,1.5,3.3,4,3.5h18c2.5-0.1,3.8-1.3,3.9-3.6v-8.2
c0.1-2-1.4-3.6-3.4-3.8C105.6,33.3,105.4,33.3,105.3,33.3z M104.6,43.9c-0.1,1-0.7,1.5-1.9,1.7H89.3c-1.3-0.3-1.8-0.7-1.9-1.7v-5.4
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0h13.1c1.1,0,2,0.8,2.1,2L104.6,43.9z"/>
<path class="st0" d="M81,25.3v-4.7c0-1.1,0.9-2.1,2.1-2.1h19c1.4-0.1,2.1,0.5,2.1,1.8v3.3c0,1.1-0.7,1.7-1.9,1.7H82.8v3.2H105
c2.3,0,3.6-1.1,3.6-3.2v-6.4c0.2-1.8-1.1-3.4-2.8-3.6c-0.3,0-0.5,0-0.8,0h-9.7v-2.6h-4.6v2.6H80.3c-2.6,0-3.9,1.2-3.9,3.9v12.3
c0,5.8-0.9,11.6-2.6,17.1l4.3,0.8c1.8-5.5,2.7-11.3,2.8-17.1v-7.2H81z"/>
<path class="st0" d="M116.2,30.4l4.4,2.4c2.6-1.9,4.4-4.6,5.1-7.6h7.8v-3.2h-7.1c0.2-1.3,0.3-2.6,0.3-3.9h6.6v-3.2h-12.3v-2h-4.6
V18h5.8c0,1.3-0.1,2.6-0.3,3.9h-6.7v3.3h5.8C120.4,27.5,118.6,29.4,116.2,30.4z"/>
<path class="st0" d="M126.5,26.7c1.2,1.8,2.1,3.8,2.9,5.8h4.9c-0.8-2-1.8-4-2.9-5.8H126.5z"/>
<path class="st0" d="M145.4,33.5h-24.7c-2.4,0.3-3.8,1.4-3.9,3.5v6.2h28.4v1.3c0,1.1-0.7,1.7-2.1,1.7h-19.7c-1.3,0-1.9-0.5-1.9-1.5
h-4.5V46c0,1.9,1.6,3.5,3.5,3.6h25.1c2.6-0.1,4-1.3,4-3.5v-9C149.2,35,147.5,33.5,145.4,33.5z M145,39.9h-23.7v-1.1
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0H143c1.3,0,2.1,0.7,2.1,1.9L145,39.9z"/>
<path class="st0" d="M147.3,14h-8.2c-2.2,0.1-3.5,1.1-3.8,2.9v11.7c0.1,1.6,1.4,2.9,3.1,2.9h8.7c1.9-0.1,3.1-1.1,3.1-2.9V17
C150.4,15.4,149.4,14.3,147.3,14z M146,26.2c0,1.4-0.7,2.1-1.9,2.1h-2.4c-1,0-1.8-0.8-1.8-1.8c0-0.1,0-0.1,0-0.2v-7
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0h2c1.1,0,2.1,0.8,2.1,1.9l0,0L146,26.2z"/>
</g>
<path class="st1" d="M67.2,44.1V20c0-2.6-1.4-5.1-3.7-6.4l-20.9-12c-2.3-1.3-5.1-1.3-7.4,0l-20.9,12c-2.3,1.3-3.7,3.8-3.7,6.4v24.1
c0,2.6,1.4,5.1,3.7,6.4l20.9,12c2.3,1.3,5.1,1.3,7.4,0l20.9-12C65.8,49.2,67.2,46.7,67.2,44.1z"/>
<path class="st0" d="M61.9,15.4L42,3.9c-1.9-1.1-4.3-1.1-6.2,0L15.9,15.4c-1.9,1.1-3.1,3.2-3.1,5.4v22.9c0,2.2,1.2,4.3,3.1,5.4
l3.8,2c0.8,0.4,0.8,1,0.8,1.9c0,0,0,0.1,0,0.1c0.1,1.6,1.8,3.5,4.2,3.5c2.3,0,4.3-1.9,4.4-4.2c0-1.6-0.8-3.1-2.3-3.9
c-0.6-0.3-1.7-0.5-2.9-0.4c-0.9,0.1-1,0.6-2.8-0.5l-2.8-1.6c-0.8-0.5-1.7-1.3-1.6-2.3V22c0-1.8,0.8-2.8,2.1-3.5L37,7.8
C38.1,7,40.2,7.2,41.5,8l16.4,9.5c2.9,1.6,3,3,3,4v19.7c0,2.3-1.5,4-2.3,4.5l-15.1,8.5C42.8,54.5,42,54,42,53.3l0-2.5
c0-0.1,0-0.3,0-0.4v-2.5c0-0.8,0.4-1.6,1.1-2l8.8-5.7c1.4-0.9,2-1.7,2-3.8L53.7,28c0-1,0.4-1.9,1.2-2.5c1.5-1.3,2-3.7,0.8-5.6
c-0.8-1.4-2.4-2.2-4-2c-1.6,0.1-2.8,1-3.5,2.4c-0.5,1-0.6,2.2-0.3,3.3c0.2,0.8,0.7,1.4,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5v7.2
c0,1.1-0.5,2.1-1.5,2.7l-5.5,2.8c-0.7,0.5-1.6,0-1.6-0.8l-0.2-17.1c0-1,0.5-1.9,1.2-2.5c0.4-0.3,0.7-0.8,1-1.3
c0.7-1.3,0.7-2.9-0.1-4.3c-0.8-1.4-2.5-2.2-4.1-2.1c-2.9,0.3-4.6,3.1-3.8,5.7c0.2,0.8,0.7,1.4,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5v9.9
c0,0.8-0.8,1.3-1.5,0.9L34,32.5c-0.7-0.4-1.2-1.2-1.2-2.1v-2.2c0-1,0.4-1.9,1.2-2.5c1.5-1.3,2-3.7,0.8-5.6c-0.8-1.3-2.4-2.1-4-2
c-2.9,0.2-4.7,3.1-3.8,5.7c0.2,0.8,0.7,1.5,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5l0,3.5c0,1,0,2,1.6,3.1l5.5,3c0.7,0.4,1.2,1.2,1.2,2.1v4.5
c0,0.8-0.8,1.3-1.5,0.9L26.6,41c-0.7-0.4-1.2-1.2-1.2-2.1l-0.2-6.1c0-1,0.4-1.8,1.1-2.5c1.4-1.3,1.9-3.4,0.9-5.3
c-0.8-1.4-2.4-2.3-4-2.2c-2.9,0.2-4.6,3-3.8,5.6c0.2,0.7,0.7,1.4,1.2,1.9c0.7,0.6,1.1,1.5,1.1,2.5l-0.5,6.8c0,1.9,0.3,2.8,1.8,3.5
l11.8,6.3c1,0.6,1.6,1.7,1.6,2.8l0,3.1c0,3.1,4.3,5.7,8.7,3.3l16.4-9.8c1.9-1,3.2-3,3.4-5.2V20.7C65,18.5,63.8,16.5,61.9,15.4z
M24.2,50.7c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C22.2,51.7,23.1,50.7,24.2,50.7z M48.7,21.5c0-1.1,0.9-2,2-2
s2,0.9,2,2c0,1.1-0.9,2-2,2S48.7,22.6,48.7,21.5z M30.6,23.8c-1.1,0-2-0.9-2-2s0.9-2,2-2c1.1,0,2,0.9,2,2S31.8,23.8,30.6,23.8z
M22.2,26.4c0-1.1,0.9-2,2-2c1.1,0,2,0.9,2,2s-0.9,2-2,2C23.1,28.4,22.2,27.5,22.2,26.4z M40,17.9c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2
c1.1,0,2,0.9,2,2C42,17,41.1,17.9,40,17.9z"/>
</svg>

+ 1
- 45
custom/public/img/logo-w.svg
File diff suppressed because it is too large
View File


+ 1
- 0
custom/public/js/placeholder-home.js View File

@@ -0,0 +1 @@
/* placeholder-home.js */

+ 1
- 0
custom/public/js/placeholder.js View File

@@ -0,0 +1 @@
/* placeholder.js */

+ 3
- 1
models/action.go View File

@@ -67,6 +67,7 @@ const (
ActionChangeUserAvatar //38
ActionCreateGrampusNPUDebugTask //39
ActionCreateGrampusGPUDebugTask //40
ActionCreateGrampusGCUDebugTask //41
)

// Action represents user operation type and other information to
@@ -380,7 +381,8 @@ func (a *Action) IsCloudbrainAction() bool {
ActionCreateGrampusGPUDebugTask,
ActionCreateGrampusNPUDebugTask,
ActionCreateGrampusNPUTrainTask,
ActionCreateGrampusGPUTrainTask:
ActionCreateGrampusGPUTrainTask,
ActionCreateGrampusGCUDebugTask:
return true
}
return false


+ 6
- 0
models/ai_model_manage.go View File

@@ -485,6 +485,12 @@ func QueryModel(opts *AiModelQueryOptions) ([]*AiModelManage, int64, error) {
return aiModelManages, count, nil
}

func QueryModelConvertCountByRepoID(repoId int64) int64 {
convert := new(AiModelConvert)
total, _ := x.Where("repo_id =?", repoId).Count(convert)
return total
}

func QueryModelConvertByRepoID(repoId int64) ([]*AiModelConvert, error) {
sess := x.NewSession()
defer sess.Close()


+ 11
- 0
models/attachment.go View File

@@ -259,6 +259,17 @@ func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) {
return getAttachmentsByCommentID(x, commentID)
}

func GetAttachmentByDatasetIdFileName(fileName string, datasetId int64) (*Attachment, error) {
attach := &Attachment{DatasetID: datasetId, Name: fileName}
has, err := x.Get(attach)
if err != nil {
return nil, err
} else if !has {
return nil, err
}
return attach, nil
}

func getAttachmentsByCommentID(e Engine, commentID int64) ([]*Attachment, error) {
attachments := make([]*Attachment, 0, 10)
return attachments, e.Where("comment_id=?", commentID).Find(&attachments)


+ 113
- 47
models/cloudbrain.go View File

@@ -30,11 +30,13 @@ const (
TypeCDCenter //成都智算中心

TypeCloudBrainAll = -1
AccCardsNumAll = -1
)

const (
NPUResource = "NPU"
GPUResource = "CPU/GPU"
GCUResource = "GCU"
AllResource = "all"

//notebook storage category
@@ -60,6 +62,7 @@ const (
JobTypeModelSafety JobType = "MODELSAFETY"
JobTypeSnn4imagenet JobType = "SNN4IMAGENET"
JobTypeBrainScore JobType = "BRAINSCORE"
JobTypeSnn4Ecoset JobType = "SNN4ECOSET"
JobTypeTrain JobType = "TRAIN"
JobTypeInference JobType = "INFERENCE"

@@ -134,6 +137,11 @@ const (
//ComputeResource
GPU = "GPU"
NPU = "NPU"
GCU = "GCU"
)

const (
AIModelPath = "aimodels/"
)

type Cloudbrain struct {
@@ -179,14 +187,14 @@ type Cloudbrain struct {
AiCenter string //grampus ai center: center_id+center_name

TrainUrl string //输出模型的obs路径
BranchName string //分支名称
BranchName string `xorm:"varchar(2550)"` //分支名称
Parameters string //传给modelarts的param参数
BootFile string //启动文件
BootFile string `xorm:"varchar(2550)"` //启动文件
DataUrl string `xorm:"varchar(3500)"` //数据集的obs路径
LogUrl string //日志输出的obs路径
PreVersionId int64 //父版本的版本id
FlavorCode string //modelarts上的规格id
Description string `xorm:"varchar(256)"` //描述
Description string `xorm:"varchar(2550)"` //描述
WorkServerNumber int //节点数
FlavorName string //规格名称
EngineName string //引擎名称
@@ -205,7 +213,7 @@ type Cloudbrain struct {
BenchmarkTypeRankLink string `xorm:"-"`
StartTime timeutil.TimeStamp
EndTime timeutil.TimeStamp
Cleared bool `xorm:"DEFAULT false"`
Cleared bool `xorm:"DEFAULT false"`
Spec *Specification `xorm:"-"`
}

@@ -302,6 +310,9 @@ func (task *Cloudbrain) IsUserHasRight(user *User) bool {
func (task *Cloudbrain) IsGPUTask() bool {
return task.ComputeResource == GPUResource
}
func (task *Cloudbrain) IsGCUTask() bool {
return task.ComputeResource == GCUResource
}
func (task *Cloudbrain) IsNPUTask() bool {
return task.ComputeResource == NPUResource
}
@@ -335,6 +346,9 @@ func IsModelArtsDebugJobTerminal(status string) bool {
func IsCloudBrainOneDebugJobTerminal(status string) bool {
return status == string(JobStopped) || status == string(JobFailed) || status == string(JobSucceeded)
}
func IsModelBenchMarkJobType(jobType string) bool {
return jobType == string(JobTypeSnn4imagenet) || jobType == string(JobTypeBrainScore) || jobType == string(JobTypeSnn4Ecoset)
}

func ParseAndSetDurationFromCloudBrainOne(result JobResultPayload, task *Cloudbrain) {
isActivated := result.JobStatus.CreatedTime > 0
@@ -449,29 +463,32 @@ type GetImagesPayload struct {

type CloudbrainsOptions struct {
ListOptions
RepoID int64 // include all repos if empty
UserID int64
JobID string
SortType string
CloudbrainIDs []int64
JobStatus []string
JobStatusNot bool
Keyword string
Type int
JobTypes []string
VersionName string
IsLatestVersion string
JobTypeNot bool
NeedRepoInfo bool
RepoIDList []int64
BeginTime time.Time
EndTime time.Time
ComputeResource string
BeginTimeUnix int64
EndTimeUnix int64
AiCenter string
NeedDeleteInfo string
Cluster string
RepoID int64 // include all repos if empty
UserID int64
JobID string
SortType string
CloudbrainIDs []int64
JobStatus []string
JobStatusNot bool
Keyword string
Type int
JobTypes []string
VersionName string
IsLatestVersion string
JobTypeNot bool
NeedRepoInfo bool
RepoIDList []int64
BeginTime time.Time
EndTime time.Time
ComputeResource string
BeginTimeUnix int64
EndTimeUnix int64
AiCenter string
NeedDeleteInfo string
Cluster string
AccCardType string
AccCardsNum int
WorkServerNumber int
}

type TaskPod struct {
@@ -1453,7 +1470,7 @@ type GetNotebookListResult struct {
NotebookList []NotebookList `json:"data"`
}

//Grampus
// Grampus
type GrampusResult struct {
ErrorCode int `json:"errorCode"`
ErrorMsg string `json:"errorMsg"`
@@ -1559,7 +1576,8 @@ type CreateGrampusJobResponse struct {

type GetGrampusJobResponse struct {
GrampusResult
JobInfo GrampusJobInfo `json:"otJob"`
JobInfo GrampusJobInfo `json:"otJob"`
ExitDiagnostics string `json:"exitDiagnostics"`
}

type GrampusNotebookResponse struct {
@@ -1823,7 +1841,7 @@ func QueryModelTrainJobVersionList(jobId string) ([]*Cloudbrain, int, error) {
return cloudbrains, int(len(cloudbrains)), nil
}

func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) {
func QueryModelTrainJobList(repoId int64) ([]*Cloudbrain, int, error) {
sess := x.NewSession()
defer sess.Close()
var cond = builder.NewCond()
@@ -1840,14 +1858,14 @@ func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) {
// builder.In("type", 0, 1),
// )

cloudbrains := make([]*CloudbrainInfo, 0)
if err := sess.Select("job_id,display_job_name").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC").
cloudbrains := make([]*Cloudbrain, 0)
if err := sess.Select("*").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC").
Find(&cloudbrains); err != nil {
return nil, 0, fmt.Errorf("Find: %v", err)
}

keys := make(map[string]string)
uniqueElements := make([]*CloudbrainInfo, 0)
uniqueElements := make([]*Cloudbrain, 0)
for _, entry := range cloudbrains {
if _, value := keys[entry.JobID]; !value {
keys[entry.JobID] = entry.DisplayJobName
@@ -1988,7 +2006,7 @@ func GetCloudbrainByID(id string) (*Cloudbrain, error) {
return getRepoCloudBrain(cb)
}

func IsCloudbrainExistByJobName(jobName string)(bool,error){
func IsCloudbrainExistByJobName(jobName string) (bool, error) {
return x.Unscoped().Exist(&Cloudbrain{
JobName: jobName,
})
@@ -2126,6 +2144,15 @@ func GetCloudbrainByName(jobName string) (*Cloudbrain, error) {
cb := &Cloudbrain{JobName: jobName}
return getRepoCloudBrain(cb)
}
func GetWaitOrRunFileNotebookByRepo(repoId int64, cloudbrainType int) (*Cloudbrain, error) {
cloudBrain := new(Cloudbrain)
has, err := x.In("status", JobWaiting, JobRunning, ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting,
ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsDeleting, ModelArtsRestarting).Where("repo_id=? and type=? and boot_file!=''", repoId, cloudbrainType).Get(cloudBrain)
if has {
return cloudBrain, err
}
return nil, err
}

func CanDelJob(isSigned bool, user *User, job *CloudbrainInfo) bool {
if !isSigned || (job.Status != string(JobStopped) && job.Status != string(JobFailed) && job.Status != string(ModelArtsStartFailed) && job.Status != string(ModelArtsCreateFailed)) {
@@ -2159,7 +2186,7 @@ func GetCloudBrainUnStoppedJob() ([]*Cloudbrain, error) {
Find(&cloudbrains)
}

func GetCloudBrainOneStoppedNotDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) {
func GetGPUStoppedNotDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) {
cloudbrains := make([]*Cloudbrain, 0, 10)
endTimeBefore := time.Now().Unix() - int64(days)*24*3600
missEndTimeBefore := endTimeBefore - 24*3600
@@ -2168,29 +2195,31 @@ func GetCloudBrainOneStoppedNotDebugJobDaysAgo(days int, limit int) ([]*Cloudbra
JobStopped, JobSucceeded, JobFailed, ModelArtsCreateFailed, ModelArtsStartFailed, ModelArtsUnavailable, ModelArtsResizFailed, ModelArtsDeleted,
ModelArtsStopped, ModelArtsTrainJobCanceled, ModelArtsTrainJobCheckFailed, ModelArtsTrainJobCompleted, ModelArtsTrainJobDeleteFailed, ModelArtsTrainJobDeployServiceFailed,
ModelArtsTrainJobFailed, ModelArtsTrainJobImageFailed, ModelArtsTrainJobKilled, ModelArtsTrainJobLost, ModelArtsTrainJobSubmitFailed, ModelArtsTrainJobSubmitModelFailed).
Where("(((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and cleared=false and type=0 and job_type != 'DEBUG'", missEndTimeBefore, endTimeBefore).
Where("(((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and cleared=false and (type=0 or (type =2 and compute_resource='CPU/GPU')) and job_type != 'DEBUG'", missEndTimeBefore, endTimeBefore).
Limit(limit).
Find(&cloudbrains)
}
/**
本方法考虑了再次调试的情况,多次调试取最后一次的任务的结束时间
*/
func GetCloudBrainOneStoppedDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) {

/*
*

本方法考虑了再次调试的情况,多次调试取最后一次的任务的结束时间
*/
func GetGPUStoppedDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) {
cloudbrains := make([]*Cloudbrain, 0, 10)
endTimeBefore := time.Now().Unix() - int64(days)*24*3600
missEndTimeBefore := endTimeBefore - 24*3600
sql:=`SELECT id,job_name,job_id from (SELECT DISTINCT ON (job_name)
sql := `SELECT id,job_name,job_id from (SELECT DISTINCT ON (job_name)
id, job_name, job_id,status,end_time,updated_unix,cleared
FROM cloudbrain
where type=0 and job_type='DEBUG'
where (type=0 or (type =2 and compute_resource='CPU/GPU')) and job_type='DEBUG'
ORDER BY job_name, updated_unix DESC) a
where status in ('STOPPED','SUCCEEDED','FAILED') and (((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and cleared=false`

return cloudbrains, x.Unscoped().SQL(sql,missEndTimeBefore, endTimeBefore).Limit(limit).Find(&cloudbrains)
return cloudbrains, x.Unscoped().SQL(sql, missEndTimeBefore, endTimeBefore).Limit(limit).Find(&cloudbrains)

}


func UpdateCloudBrainRecordsCleared(ids []int64) error {
pageSize := 150
n := len(ids) / pageSize
@@ -2422,18 +2451,44 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
)
}

if opts.WorkServerNumber > 0 {
if opts.WorkServerNumber == 1 {
cond = cond.And(builder.Or(
builder.Eq{"cloudbrain.work_server_number": 0},
builder.Eq{"cloudbrain.work_server_number": 1},
builder.IsNull{"cloudbrain.work_server_number"},
))
} else {
cond = cond.And(
builder.Eq{"cloudbrain.work_server_number": opts.WorkServerNumber},
)
}
}

if opts.AccCardType != "" {
cond = cond.And(builder.Eq{"cloudbrain_spec.acc_card_type": opts.AccCardType})
}
if opts.AccCardsNum >= 0 {
cond = cond.And(builder.Eq{"cloudbrain_spec.acc_cards_num": opts.AccCardsNum})
}

var count int64
var err error
condition := "cloudbrain.user_id = `user`.id"
if len(opts.Keyword) == 0 {
count, err = sess.Unscoped().Where(cond).Count(new(Cloudbrain))
count, err = sess.Table(&Cloudbrain{}).Unscoped().Where(cond).
Join("left", "`user`", condition).
Join("left", "cloudbrain_spec", "cloudbrain.id = cloudbrain_spec.cloudbrain_id").
Count(new(CloudbrainInfo))
} else {
lowerKeyWord := strings.ToLower(opts.Keyword)

cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord},
builder.Like{"LOWER(cloudbrain.display_job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord}))
count, err = sess.Table(&Cloudbrain{}).Unscoped().Where(cond).
Join("left", "`user`", condition).Count(new(CloudbrainInfo))
Join("left", "`user`", condition).
Join("left", "cloudbrain_spec", "cloudbrain.id = cloudbrain_spec.cloudbrain_id").
Count(new(CloudbrainInfo))

}

@@ -2455,6 +2510,7 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum)
if err := sess.Table(&Cloudbrain{}).Unscoped().Where(cond).
Join("left", "`user`", condition).
Join("left", "cloudbrain_spec", "cloudbrain.id = cloudbrain_spec.cloudbrain_id").
Find(&cloudbrains); err != nil {
return nil, 0, fmt.Errorf("Find: %v", err)
}
@@ -2609,6 +2665,8 @@ type DatasetInfo struct {
DataLocalPath string
Name string
FullName string
Type int
Size int64
}

func GetDatasetInfo(uuidStr string, grampusType ...string) (map[string]DatasetInfo, string, error) {
@@ -2648,8 +2706,14 @@ func GetDatasetInfo(uuidStr string, grampusType ...string) (map[string]DatasetIn
if len(grampusType) > 0 {
if grampusType[0] == GPU {
dataLocalPath = setting.Attachment.Minio.BasePath + path.Join(attach.UUID[0:1], attach.UUID[1:2]) + "/" + attach.UUID
} else {
} else if grampusType[0] == NPU {
dataLocalPath = setting.BasePath + path.Join(attach.UUID[0:1], attach.UUID[1:2]) + "/" + attach.UUID + "/"
} else if grampusType[0] == GCU {
if attach.Type == TypeCloudBrainOne {
dataLocalPath = setting.Attachment.Minio.BasePath + path.Join(attach.UUID[0:1], attach.UUID[1:2]) + "/" + attach.UUID
} else {
dataLocalPath = setting.BasePath + path.Join(attach.UUID[0:1], attach.UUID[1:2]) + "/" + attach.UUID + "/"
}
}

} else {
@@ -2664,6 +2728,8 @@ func GetDatasetInfo(uuidStr string, grampusType ...string) (map[string]DatasetIn
DataLocalPath: dataLocalPath,
Name: fileName,
FullName: attach.Name,
Type: attach.Type,
Size: attach.Size,
}
if i == 0 {
datasetNames = attach.Name


+ 10
- 1
models/repo_statistic.go View File

@@ -36,7 +36,7 @@ type RepoStatistic struct {
NumDevMonths int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
RepoSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
DatasetSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"model"`
NumWikiViews int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumCommits int64 `xorm:"NOT NULL DEFAULT 0" json:"commit"`
NumCommitsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
@@ -55,6 +55,15 @@ type RepoStatistic struct {
NumIssuesGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumCommentsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`

NumDatasetFile int64 `xorm:"NOT NULL DEFAULT 0" json:"datasetFiles"`
NumCloudbrain int64 `xorm:"NOT NULL DEFAULT 0" json:"cloudbrains"`
NumModelConvert int64 `xorm:"NOT NULL DEFAULT 0" json:"modelConverts"`

NumDatasetFileAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumCloudbrainAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumModelConvertAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"- "`
NumModelsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"- "`

Impact float64 `xorm:"NOT NULL DEFAULT 0" json:"impact"`
Completeness float64 `xorm:"NOT NULL DEFAULT 0" json:"completeness"`
Liveness float64 `xorm:"NOT NULL DEFAULT 0" json:"liveness"`


+ 1
- 0
models/task_config.go View File

@@ -39,6 +39,7 @@ func GetTaskTypeFromAction(a ActionType) TaskType {
ActionCreateGrampusGPUDebugTask,
ActionCreateGrampusNPUDebugTask,
ActionCreateGrampusNPUTrainTask,
ActionCreateGrampusGCUDebugTask,
ActionCreateGrampusGPUTrainTask:
return TaskCreateCloudbrainTask
case ActionCreateRepo:


+ 6
- 1
models/user.go View File

@@ -16,6 +16,7 @@ import (
"fmt"
_ "image/jpeg" // Needed for jpeg support
"image/png"
"math/rand"
"os"
"path/filepath"
"regexp"
@@ -495,7 +496,11 @@ func (u *User) RealSizedAvatarLink(size int) string {
// may either be a sub-URL to this site, or a full URL to an external avatar
// service.
func (u *User) RelAvatarLink() string {
return u.SizedRelAvatarLink(base.DefaultAvatarSize)
append := ""
if u.UseCustomAvatar {
append = "?" + fmt.Sprint(rand.Intn(100))
}
return u.SizedRelAvatarLink(base.DefaultAvatarSize) + append
}

// AvatarLink returns user avatar absolute link.


+ 24
- 0
models/user_analysis_for_activity.go View File

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

import (
"encoding/json"
"fmt"
"time"

@@ -450,19 +451,42 @@ func QueryUserLoginInfo(userIds []int64) []*UserLoginLog {
return loginList
}

var WeekBonusData = make(map[int64][]int)

func QueryUserAnnualReport(userId int64) *UserSummaryCurrentYear {
statictisSess := xStatistic.NewSession()
defer statictisSess.Close()
log.Info("userId=" + fmt.Sprint(userId))
if len(WeekBonusData) == 0 {
WeekBonusData = getBonusWeekDataMap()
}

reList := make([]*UserSummaryCurrentYear, 0)
err := statictisSess.Select("*").Table(new(UserSummaryCurrentYear)).Where("id=" + fmt.Sprint(userId)).Find(&reList)
if err == nil {
if len(reList) > 0 {
record, ok := WeekBonusData[userId]
if ok {
bonusInfo := make(map[string]int)
bonusInfo["order"] = record[0]
bonusInfo["money"] = record[1]
bonusInfo["week"] = record[2]
bonusInfo["num"] = record[3]
bonusInfoJson, _ := json.Marshal(bonusInfo)
reList[0].WeekBonusData = string(bonusInfoJson)
}
return reList[0]
}
} else {
log.Info("error:=" + err.Error())
}
dbuser, err := GetUserByID(userId)
if err == nil {
return &UserSummaryCurrentYear{
ID: dbuser.ID,
Name: dbuser.Name,
RegistDate: dbuser.CreatedUnix,
}
}
return nil
}

+ 176
- 45
models/user_business_analysis.go View File

@@ -330,7 +330,7 @@ func QueryUserStaticDataForUserDefine(opts *UserBusinessAnalysisQueryOptions, wi
DataDate := currentTimeNow.Format("2006-01-02 15:04")

CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap, _ := queryCommitAction(start_unix, end_unix, 5)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
IssueCountMap := queryCreateIssue(start_unix, end_unix)

CommentCountMap := queryComment(start_unix, end_unix)
@@ -586,7 +586,7 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS
startTime := currentTimeNow.AddDate(0, 0, -1)

CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap, _ := queryCommitAction(start_unix, end_unix, 5)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
IssueCountMap := queryCreateIssue(start_unix, end_unix)

CommentCountMap := queryComment(start_unix, end_unix)
@@ -762,7 +762,8 @@ func RefreshUserYearTable(pageStartTime time.Time, pageEndTime time.Time) {
end_unix := pageEndTime.Unix()

CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap, mostActiveMap := queryCommitAction(start_unix, end_unix, 5)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
mostActiveMap := queryMostActiveCommitAction(start_unix, end_unix)
IssueCountMap := queryCreateIssue(start_unix, end_unix)

CommentCountMap := queryComment(start_unix, end_unix)
@@ -841,9 +842,9 @@ func RefreshUserYearTable(pageStartTime time.Time, pageEndTime time.Time) {
repoInfo := getRepoDetailInfo(DetailInfoMap, dateRecordAll.ID, MostDownloadMap)
dataSetInfo, datasetscore := getDataSetInfo(dateRecordAll.ID, CreatedDataset, dataSetDownloadMap, CommitDatasetNumMap, CollectedDataset)
scoreMap["datasetscore"] = datasetscore
codeInfo, codescore := getCodeInfo(dateRecordAll)
codeInfo, codescore := getCodeInfo(&dateRecordAll)
scoreMap["codescore"] = codescore
cloudBrainInfo := getCloudBrainInfo(dateRecordAll, CloudBrainTaskItemMap, scoreMap)
cloudBrainInfo := getCloudBrainInfo(&dateRecordAll, CloudBrainTaskItemMap, scoreMap)
playARoll := getPlayARoll(bonusMap, dateRecordAll.Name, scoreMap)
re := &UserSummaryCurrentYear{
ID: dateRecordAll.ID,
@@ -880,6 +881,76 @@ func isUserYearData(tableName string) bool {
return false
}

func getBonusWeekDataMap() map[int64][]int {
bonusMap := make(map[int64][]int)
url := setting.RecommentRepoAddr + "bonus/weekdata/record.txt"
content, err := GetContentFromPromote(url)
if err == nil {
filenames := strings.Split(content, "\n")
for i := 0; i < len(filenames); i++ {
if strings.HasSuffix(filenames[i], "\r") {
filenames[i] = filenames[i][0 : len(filenames[i])-len("\r")]
}
url = setting.RecommentRepoAddr + "bonus/weekdata/" + filenames[i]
csvContent, err1 := GetContentFromPromote(url)
if err1 == nil {
//read csv
lines := strings.Split(csvContent, "\n")
for j := 1; j < len(lines); j++ {
if strings.HasSuffix(lines[j], "\r") {
lines[j] = lines[j][0 : len(lines[j])-len("\r")]
}
log.Info("aLine=" + lines[j])
aLine := strings.Split(lines[j], ",")
if len(aLine) < 4 {
continue
}
userId := getInt64Value(aLine[0])
order := getIntValue(aLine[2])
money := getIntValue(aLine[3])
week, num := getWeekAndNum(filenames[i])
//log.Info("userId=" + fmt.Sprint(userId) + " order=" + fmt.Sprint(order) + " money=" + fmt.Sprint(money) + " week=" + fmt.Sprint(week) + " num=" + fmt.Sprint(num))
//email := lines[2]
record, ok := bonusMap[userId]
if !ok {
record = make([]int, 4)
record[0] = order
record[1] = money
record[2] = week
record[3] = num
bonusMap[userId] = record
} else {
if record[0] > order {
record[0] = order
record[1] = money
record[2] = week
record[3] = num
} else {
if record[0] == order && record[1] < money {
record[1] = money
record[2] = week
record[3] = num
}
}
}
}
}
}
}
return bonusMap
}

func getWeekAndNum(name string) (int, int) {
name = name[0 : len(name)-4]
tmp := strings.Split(name, "_")
if len(tmp) == 2 {
week := getIntValue(tmp[0])
num := getIntValue(tmp[1])
return week, num
}
return 0, 0
}

func getBonusMap() map[string]map[string]int {
bonusMap := make(map[string]map[string]int)
url := setting.RecommentRepoAddr + "bonus/record.txt"
@@ -887,12 +958,18 @@ func getBonusMap() map[string]map[string]int {
if err == nil {
filenames := strings.Split(content, "\n")
for i := 0; i < len(filenames); i++ {
if strings.HasSuffix(filenames[i], "\r") {
filenames[i] = filenames[i][0 : len(filenames[i])-len("\r")]
}
url = setting.RecommentRepoAddr + "bonus/" + filenames[i]
csvContent, err1 := GetContentFromPromote(url)
if err1 == nil {
//read csv
lines := strings.Split(csvContent, "\n")
for j := 1; j < len(lines); j++ {
if strings.HasSuffix(lines[j], "\r") {
lines[j] = lines[j][0 : len(lines[j])-len("\r")]
}
aLine := strings.Split(lines[j], ",")
if len(aLine) < 7 {
continue
@@ -923,6 +1000,14 @@ func getIntValue(val string) int {
return 0
}

func getInt64Value(val string) int64 {
i, err := strconv.ParseInt(val, 10, 64)
if err == nil {
return i
}
return 0
}

func getPlayARoll(bonusMap map[string]map[string]int, userName string, scoreMap map[string]float64) string {
bonusInfo := make(map[string]string)
record, ok := bonusMap[userName]
@@ -943,7 +1028,7 @@ func getPlayARoll(bonusMap map[string]map[string]int, userName string, scoreMap
}
}

func getCloudBrainInfo(dateRecordAll UserBusinessAnalysisAll, CloudBrainTaskItemMap map[string]int, scoreMap map[string]float64) string {
func getCloudBrainInfo(dateRecordAll *UserBusinessAnalysisAll, CloudBrainTaskItemMap map[string]int, scoreMap map[string]float64) string {
trainscore := 0.0
debugscore := 0.0
runtime := 0.0
@@ -959,19 +1044,16 @@ func getCloudBrainInfo(dateRecordAll UserBusinessAnalysisAll, CloudBrainTaskItem
trainscore = float64(dateRecordAll.GpuTrainJob+dateRecordAll.NpuTrainJob) / float64(50)
}
cloudBrainInfo["inference_task_num"] = fmt.Sprint(dateRecordAll.NpuInferenceJob + CloudBrainTaskItemMap[fmt.Sprint(dateRecordAll.ID)+"_GpuInferenceJob"])
cloudBrainInfo["benchmark_task_num"] = fmt.Sprint(dateRecordAll.GpuBenchMarkJob)
cloudBrainInfo["card_runtime"] = fmt.Sprint(dateRecordAll.CloudBrainRunTime)
if dateRecordAll.CloudBrainRunTime >= 100 {
runtime = float64(dateRecordAll.CloudBrainRunTime) / float64(100)
}
cloudBrainInfo["card_runtime_money"] = fmt.Sprint(dateRecordAll.CloudBrainRunTime * 5)
cloudBrainInfo["CloudBrainOne"] = fmt.Sprint(CloudBrainTaskItemMap[fmt.Sprint(dateRecordAll.ID)+"_CloudBrainOne"])
cloudBrainInfo["CloudBrainTwo"] = fmt.Sprint(CloudBrainTaskItemMap[fmt.Sprint(dateRecordAll.ID)+"_CloudBrainTwo"])
cloudBrainInfo["C2Net"] = fmt.Sprint(CloudBrainTaskItemMap[fmt.Sprint(dateRecordAll.ID)+"_C2Net"])

cloudBrainInfoJson, _ := json.Marshal(cloudBrainInfo)
scoreMap["trainscore"] = trainscore
scoreMap["debugscore"] = debugscore
scoreMap["runtime"] = runtime
return string(cloudBrainInfoJson)
} else {
scoreMap["trainscore"] = trainscore
@@ -981,7 +1063,7 @@ func getCloudBrainInfo(dateRecordAll UserBusinessAnalysisAll, CloudBrainTaskItem
}
}

func getCodeInfo(dateRecordAll UserBusinessAnalysisAll) (string, float64) {
func getCodeInfo(dateRecordAll *UserBusinessAnalysisAll) (string, float64) {
if dateRecordAll.CommitCount > 0 {
codeInfo := make(map[string]string)
codeInfo["commit_count"] = fmt.Sprint(dateRecordAll.CommitCount)
@@ -1165,7 +1247,7 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time,

DataDate := CountDate.Format("2006-01-02")
CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap, _ := queryCommitAction(start_unix, end_unix, 5)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
IssueCountMap := queryCreateIssue(start_unix, end_unix)

CommentCountMap := queryComment(start_unix, end_unix)
@@ -1311,7 +1393,7 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time,
useMetrics.TotalActivateRegistUser = getMapKeyStringValue("TotalActivateRegistUser", userMetrics)
useMetrics.TotalHasActivityUser = getMapKeyStringValue("TotalHasActivityUser", userMetrics)
useMetrics.CurrentDayRegistUser = getMapKeyStringValue("CurrentDayRegistUser", userMetrics)
count, err = sess.Where("type=0").Count(new(User))
count, err = sess.Where("type=0 and created_unix<=" + fmt.Sprint(end_unix)).Count(new(User))
if err != nil {
log.Info("query user error. return.")
}
@@ -1659,52 +1741,48 @@ func queryPullRequest(start_unix int64, end_unix int64) map[int64]int {
return resultMap
}

func queryCommitAction(start_unix int64, end_unix int64, actionType int64) (map[int64]int, map[int64]map[string]int) {
func queryMostActiveCommitAction(start_unix int64, end_unix int64) map[int64]map[string]int {
sess := x.NewSession()
defer sess.Close()
resultMap := make(map[int64]int)
mostActiveMap := make(map[int64]map[string]int)
cond := "user_id=act_user_id and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)

count, err := sess.Where(cond).Count(new(Action))
if err != nil {
log.Info("query action error. return.")
return resultMap, mostActiveMap
return mostActiveMap
}

var indexTotal int64
indexTotal = 0
for {
sess.Select("id,user_id,op_type,act_user_id,created_unix").Table("action").Where(cond).OrderBy("id asc").Limit(PAGE_SIZE, int(indexTotal))
actionList := make([]*Action, 0)
sess.Find(&actionList)

log.Info("query action size=" + fmt.Sprint(len(actionList)))
actionList, err := sess.QueryInterface("select id,user_id,op_type,act_user_id,created_unix from public.action where " + cond + " order by id asc limit " + fmt.Sprint(PAGE_SIZE) + " offset " + fmt.Sprint(indexTotal))
if err != nil {
log.Info("error:" + err.Error())
continue
}
log.Info("query mostactive action size=" + fmt.Sprint(len(actionList)))
for _, actionRecord := range actionList {
if int64(actionRecord.OpType) == actionType {
if _, ok := resultMap[actionRecord.UserID]; !ok {
resultMap[actionRecord.UserID] = 1
} else {
resultMap[actionRecord.UserID] += 1
}
}
key := getDate(actionRecord.CreatedUnix)
if _, ok := mostActiveMap[actionRecord.UserID]; !ok {
userId := convertInterfaceToInt64(actionRecord["user_id"])
created_unix := timeutil.TimeStamp(convertInterfaceToInt64(actionRecord["created_unix"]))
key := getDate(created_unix)
if _, ok := mostActiveMap[userId]; !ok {
tmpMap := make(map[string]int)
tmpMap[key] = 1
mostActiveMap[actionRecord.UserID] = tmpMap
mostActiveMap[userId] = tmpMap
} else {
mostActiveMap[actionRecord.UserID][key] = getMapKeyStringValue(key, mostActiveMap[actionRecord.UserID]) + 1
mostActiveMap[userId][key] = getMapKeyStringValue(key, mostActiveMap[userId]) + 1
}
utcTime := actionRecord.CreatedUnix.AsTime()
utcTime := created_unix.AsTime()
hour := utcTime.Hour()
if hour >= 0 && hour <= 5 {
key = "hour_hour"
if getMapKeyStringValue(key, mostActiveMap[actionRecord.UserID]) < hour {
mostActiveMap[actionRecord.UserID][key] = hour
mostActiveMap[actionRecord.UserID]["hour_day"] = utcTime.Day()
mostActiveMap[actionRecord.UserID]["hour_month"] = int(utcTime.Month())
mostActiveMap[actionRecord.UserID]["hour_year"] = utcTime.Year()
if getMapKeyStringValue(key, mostActiveMap[userId]) < hour {
mostActiveMap[userId][key] = hour
mostActiveMap[userId]["hour_day"] = utcTime.Day()
mostActiveMap[userId]["hour_month"] = int(utcTime.Month())
mostActiveMap[userId]["hour_year"] = utcTime.Year()
}
}
}
@@ -1713,9 +1791,60 @@ func queryCommitAction(start_unix int64, end_unix int64, actionType int64) (map[
break
}
}
return mostActiveMap
}

return resultMap, mostActiveMap
func queryCommitAction(start_unix int64, end_unix int64, actionType int64) map[int64]int {
sess := x.NewSession()
defer sess.Close()
resultMap := make(map[int64]int)
cond := "op_type=" + fmt.Sprint(actionType) + " and user_id=act_user_id and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
count, err := sess.Where(cond).Count(new(Action))
if err != nil {
log.Info("query action error. return.")
return resultMap
}
var indexTotal int64
indexTotal = 0
for {
actionList, err := sess.QueryInterface("select id,user_id,op_type,act_user_id,created_unix from public.action where " + cond + " order by id asc limit " + fmt.Sprint(PAGE_SIZE) + " offset " + fmt.Sprint(indexTotal))
if err != nil {
log.Info("error:" + err.Error())
continue
}
log.Info("query action size=" + fmt.Sprint(len(actionList)))
for _, actionRecord := range actionList {
userId := convertInterfaceToInt64(actionRecord["user_id"])

if _, ok := resultMap[userId]; !ok {
resultMap[userId] = 1
} else {
resultMap[userId] += 1
}

}
indexTotal += PAGE_SIZE
if indexTotal >= count {
break
}
}
return resultMap
}

func convertInterfaceToInt64(obj interface{}) int64 {
switch obj.(type) {
case int8:
return int64(obj.(int8))
case int16:
return int64(obj.(int16))
case int32:
return int64(obj.(int32))
case int64:
return obj.(int64)
}
return 0
}

func getDate(createTime timeutil.TimeStamp) string {
return createTime.Format("2006-01-02")
}
@@ -2408,15 +2537,16 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s
resultItemMap := make(map[string]int)

cond := " created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
count, err := sess.Where(cond).Count(new(Cloudbrain))
count, err := sess.Where(cond).Unscoped().Count(new(Cloudbrain))
if err != nil {
log.Info("query cloudbrain error. return.")
return resultMap, resultItemMap
}
log.Info("cloudbrain count=" + fmt.Sprint(count))
var indexTotal int64
indexTotal = 0
for {
sess.Select("id,job_type,user_id,duration,train_job_duration,type").Table("cloudbrain").Unscoped().Where(cond).OrderBy("id asc").Limit(PAGE_SIZE, int(indexTotal))
sess.Select("id,job_type,user_id,duration,train_job_duration,type,compute_resource").Table("cloudbrain").Unscoped().Where(cond).OrderBy("id asc").Limit(PAGE_SIZE, int(indexTotal))
cloudTaskList := make([]*Cloudbrain, 0)
sess.Find(&cloudTaskList)
log.Info("query cloudbrain size=" + fmt.Sprint(len(cloudTaskList)))
@@ -2435,6 +2565,8 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s
setMapKey("NpuTrainJob", cloudTaskRecord.UserID, 1, resultItemMap)
} else if cloudTaskRecord.JobType == "INFERENCE" {
setMapKey("NpuInferenceJob", cloudTaskRecord.UserID, 1, resultItemMap)
} else if cloudTaskRecord.JobType == "BENCHMARK" || cloudTaskRecord.JobType == "MODELSAFETY" {
setMapKey("GpuBenchMarkJob", cloudTaskRecord.UserID, 1, resultItemMap)
} else {
setMapKey("NpuDebugJob", cloudTaskRecord.UserID, 1, resultItemMap)
}
@@ -2444,12 +2576,12 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s
setMapKey("GpuTrainJob", cloudTaskRecord.UserID, 1, resultItemMap)
} else if cloudTaskRecord.JobType == "INFERENCE" {
setMapKey("GpuInferenceJob", cloudTaskRecord.UserID, 1, resultItemMap)
} else if cloudTaskRecord.JobType == "BENCHMARK" {
} else if cloudTaskRecord.JobType == "BENCHMARK" || cloudTaskRecord.JobType == "MODELSAFETY" {
setMapKey("GpuBenchMarkJob", cloudTaskRecord.UserID, 1, resultItemMap)
} else {
setMapKey("GpuDebugJob", cloudTaskRecord.UserID, 1, resultItemMap)
}
} else if cloudTaskRecord.Type == 2 {
} else if cloudTaskRecord.Type == 2 || cloudTaskRecord.Type == 3 {
setMapKey("C2Net", cloudTaskRecord.UserID, 1, resultItemMap)
if cloudTaskRecord.ComputeResource == NPUResource {
if cloudTaskRecord.JobType == "TRAIN" {
@@ -2471,7 +2603,6 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s
break
}
}

return resultMap, resultItemMap
}



+ 3
- 3
models/user_business_struct.go View File

@@ -18,9 +18,9 @@ type UserSummaryCurrentYear struct {
CodeInfo string `xorm:"varchar(500)"` //代码提交次数,提交总代码行数,最晚的提交时间
CloudBrainInfo string `xorm:"varchar(1000)"` //,创建了XX 个云脑任务,调试任务XX 个,训练任务XX 个,推理任务XX 个,累计运行了XXXX 卡时,累计节省xxxxx 元
//这些免费的算力资源分别有,XX% 来自鹏城云脑1,XX% 来自鹏城云脑2,XX% 来自智算网络
PlayARoll string `xorm:"varchar(500)"` //你参加了XX 次“我为开源打榜狂”活动,累计上榜XX 次,总共获得了社区XXX 元的激励
Label string `xorm:"varchar(500)"`
PlayARoll string `xorm:"varchar(500)"` //你参加了XX 次“我为开源打榜狂”活动,累计上榜XX 次,总共获得了社区XXX 元的激励
WeekBonusData string `xorm:"-"`
Label string `xorm:"varchar(500)"`
}

type UserBusinessAnalysisCurrentYear struct {


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

@@ -28,6 +28,7 @@ type CreateModelArtsNotebookForm struct {
LabelName string `form:"label_names"`
PreTrainModelUrl string `form:"pre_train_model_url"`
SpecId int64 `form:"spec_id" binding:"Required"`
DatasetName string `form:"dataset_name"`
}

func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {


+ 7
- 19
modules/cloudbrain/cloudbrain.go View File

@@ -32,10 +32,10 @@ const (
Snn4imagenetMountPath = "/snn4imagenet"
BrainScoreMountPath = "/brainscore"
TaskInfoName = "/taskInfo"
Snn4imagenetCommand = `/opt/conda/bin/python /snn4imagenet/testSNN_script.py --modelname '%s' --modelpath '/dataset' --modeldescription '%s' >/model/benchmark-log.txt`
BrainScoreCommand = `bash /brainscore/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/dataset' -d '%s' >/model/benchmark-log.txt`
SubTaskName = "task1"
Snn4imagenetCommand = `/opt/conda/bin/python /benchmark/testSNN_script.py --modelname '%s' --modelpath '/pretrainmodel/%s' --modeldescription '%s' >/model/benchmark-log.txt`
BrainScoreCommand = `bash /benchmark/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/pretrainmodel/%s' -d '%s' >/model/benchmark-log.txt`
Snn4EcosetCommand = `/opt/conda/bin/python /benchmark/testSNN_script.py --datapath '/dataset' --modelname '%s' --modelpath '/pretrainmodel/%s' --modeldescription '%s' >/model/benchmark-log.txt`
SubTaskName = "task1"

Success = "S000"

@@ -257,20 +257,6 @@ func GenerateTask(req GenerateCloudBrainTaskReq) (string, error) {
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: req.Snn4ImageNetPath,
MountPath: Snn4imagenetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: req.BrainScorePath,
MountPath: BrainScoreMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: req.ResultPath,
@@ -406,7 +392,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) (string, error) {
}

func IsBenchmarkJob(jobType string) bool {
return string(models.JobTypeModelSafety) == jobType || string(models.JobTypeBenchmark) == jobType || string(models.JobTypeBrainScore) == jobType || string(models.JobTypeSnn4imagenet) == jobType
return string(models.JobTypeModelSafety) == jobType || string(models.JobTypeBenchmark) == jobType || string(models.JobTypeBrainScore) == jobType || string(models.JobTypeSnn4imagenet) == jobType || string(models.JobTypeSnn4Ecoset) == jobType
}

func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTypes ...models.JobType) int64 {
@@ -675,6 +661,7 @@ func IsElementExist(s []string, str string) bool {
return false
}


func GetCloudBrainByIdOrJobId(id string, initialQuery string) (*models.Cloudbrain, error) {
_, err := strconv.ParseInt(id, 10, 64)
var job *models.Cloudbrain
@@ -709,6 +696,7 @@ type GenerateModelArtsNotebookReq struct {

ImageId string
AutoStopDurationMs int64
BranchName string

Spec *models.Specification
ModelName string


+ 6
- 1
modules/context/auth.go View File

@@ -81,7 +81,12 @@ func Toggle(options *ToggleOptions) macaron.Handler {

// Redirect to dashboard if user tries to visit any non-login page.
if options.SignOutRequired && ctx.IsSigned && ctx.Req.URL.RequestURI() != "/" {
ctx.Redirect(setting.AppSubURL + "/")
redirectTo := ctx.Query("redirect_to")
if len(redirectTo) > 0 {
ctx.Redirect(redirectTo)
} else {
ctx.Redirect(setting.AppSubURL + "/")
}
return
}



+ 7
- 5
modules/convert/cloudbrain.go View File

@@ -28,14 +28,13 @@ func ToCloudBrain(task *models.Cloudbrain) *api.Cloudbrain {
BootFile: task.BootFile,
Description: task.Description,
ModelName: task.ModelName,
ModelVersion: task.ModelVersion,
CkptName: task.CkptName,
VersionName: task.VersionName,
ModelVersion: task.ModelVersion,
CkptName: task.CkptName,

StartTime: int64(task.StartTime),
EndTime: int64(task.EndTime),

Spec: ToSpecification(task.Spec),
Spec: ToSpecification(task.Spec),
}
}
func ToAttachment(attachment *models.Attachment) *api.AttachmentShow {
@@ -89,6 +88,9 @@ func ToDataset(dataset *models.Dataset) *api.Dataset {
}

func ToSpecification(s *models.Specification) *api.SpecificationShow {
if s == nil {
return nil
}
return &api.SpecificationShow{
ID: s.ID,
AccCardsNum: s.AccCardsNum,


+ 65
- 10
modules/grampus/grampus.go View File

@@ -19,6 +19,7 @@ const (

ProcessorTypeNPU = "npu.huawei.com/NPU"
ProcessorTypeGPU = "nvidia.com/gpu"
ProcessorTypeGCU = "enflame-tech.com/gcu"

GpuWorkDir = "/tmp/"
NpuWorkDir = "/cache/"
@@ -108,6 +109,7 @@ type GenerateNotebookJobReq struct {
Spec *models.Specification
CodeName string
ModelPath string //参考启智GPU调试, 挂载/model目录用户的模型可以输出到这个目录
ModelStorageType int
}

func getEndPoint() string {
@@ -148,6 +150,36 @@ func getDatasetGPUGrampus(datasetInfos map[string]models.DatasetInfo) ([]models.
}
return datasetGrampus, command
}
func getDatasetGCUGrampus(datasetInfos map[string]models.DatasetInfo) ([]models.GrampusDataset, string) {
var datasetGrampus []models.GrampusDataset
var command = ""
obsEndPoint := getEndPoint()
for uuid, datasetInfo := range datasetInfos {
if datasetInfo.Type == models.TypeCloudBrainOne {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: datasetInfo.FullName,
Bucket: setting.Attachment.Minio.Bucket,
EndPoint: setting.Attachment.Minio.Endpoint,
ObjectKey: datasetInfo.DataLocalPath,
ReadOnly: true,
ContainerPath: "/dataset1/" + datasetInfo.Name,
})

command += "cp /dataset1/'" + datasetInfo.Name + "'/" + uuid + " /dataset/'" + datasetInfo.FullName + "';"

} else {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: datasetInfo.FullName,
Bucket: setting.Bucket,
EndPoint: obsEndPoint,
ObjectKey: datasetInfo.DataLocalPath + datasetInfo.FullName,
ContainerPath: "/dataset/" + datasetInfo.Name,
})
}

}
return datasetGrampus, command
}

func GenerateNotebookJob(ctx *context.Context, req *GenerateNotebookJobReq) (jobId string, err error) {
createTime := timeutil.TimeStampNow()
@@ -178,25 +210,45 @@ func GenerateNotebookJob(ctx *context.Context, req *GenerateNotebookJobReq) (job
imageUrl = ""
req.Command = ""
} else {
datasetGrampus, cpCommand = getDatasetGPUGrampus(req.DatasetInfos)
if ProcessorTypeGCU == req.ProcessType {
datasetGrampus, cpCommand = getDatasetGCUGrampus(req.DatasetInfos)
} else {
datasetGrampus, cpCommand = getDatasetGPUGrampus(req.DatasetInfos)
}
if len(req.ModelName) != 0 {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: req.ModelName,
Bucket: setting.Attachment.Minio.Bucket,
EndPoint: setting.Attachment.Minio.Endpoint,
ObjectKey: req.PreTrainModelPath,
ReadOnly: true,
ContainerPath: cloudbrain.PretrainModelMountPath,
})
if req.ModelStorageType == models.TypeCloudBrainOne {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: req.ModelName,
Bucket: setting.Attachment.Minio.Bucket,
EndPoint: setting.Attachment.Minio.Endpoint,
ObjectKey: req.PreTrainModelPath,
ReadOnly: true,
ContainerPath: cloudbrain.PretrainModelMountPath,
})
} else {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: req.ModelName,
Bucket: setting.Bucket,
EndPoint: getEndPoint(),
ReadOnly: true,
ObjectKey: req.PreTrainModelPath,
ContainerPath: cloudbrain.PretrainModelMountPath,
})
}

}
codeArchiveName := cloudbrain.DefaultBranchName + ".zip"
codeGrampus = models.GrampusDataset{
Name: req.CodeName,
Bucket: setting.Attachment.Minio.Bucket,
EndPoint: setting.Attachment.Minio.Endpoint,
ObjectKey: req.CodeStoragePath + cloudbrain.DefaultBranchName + ".zip",
ObjectKey: req.CodeStoragePath + codeArchiveName,
ReadOnly: false,
ContainerPath: cloudbrain.CodeMountPath,
}
if ProcessorTypeGCU == req.ProcessType {
imageUrl = ""
}
req.Command = fmt.Sprintf(CommandGpuDebug, cpCommand, setting.CullIdleTimeout, setting.CullIdleTimeout, setting.CullInterval, setting.CullIdleTimeout, setting.CullInterval)
log.Info("debug command:" + req.Command)

@@ -215,6 +267,7 @@ func GenerateNotebookJob(ctx *context.Context, req *GenerateNotebookJobReq) (job
AutoStopDuration: autoStopDurationMs,
Capacity: setting.Capacity,
Command: req.Command,
CenterID: req.Spec.GetAvailableCenterIds(ctx.User.ID),
},
},
})
@@ -263,6 +316,8 @@ func GenerateNotebookJob(ctx *context.Context, req *GenerateNotebookJobReq) (job
actionType = models.ActionCreateGrampusNPUDebugTask
} else if req.ComputeResource == models.GPUResource {
actionType = models.ActionCreateGrampusGPUDebugTask
} else if req.ComputeResource == models.GCUResource {
actionType = models.ActionCreateGrampusGCUDebugTask
}
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {


+ 0
- 1
modules/grampus/resty.go View File

@@ -198,7 +198,6 @@ sendjob:
SetAuthToken(TOKEN).
SetResult(&result).
Get(HOST + urlTrainJob + "/" + jobID)

if err != nil {
return nil, fmt.Errorf("resty GetJob: %v", err)
}


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

@@ -1,13 +1,9 @@
package modelarts

import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"path"
"strconv"
"strings"

@@ -26,9 +22,9 @@ import (
const (
//notebook

storageTypeOBS = "obs"
autoStopDuration = 4 * 60 * 60
AutoStopDurationMs = 4 * 60 * 60 * 1000
storageTypeOBS = "obs"
autoStopDuration = 4 * 60 * 60
AutoStopDurationMs = 4 * 60 * 60 * 1000

CodePath = "/code/"
OutputPath = "/output/"
@@ -172,7 +168,6 @@ type OrgMultiNode struct {
Node []int `json:"node"`
}


type Parameters struct {
Parameter []struct {
Label string `json:"label"`
@@ -239,6 +234,7 @@ func GenerateNotebook2(ctx *context.Context, req cloudbrain.GenerateModelArtsNot
ComputeResource: models.NPUResource,
Image: imageName,
BootFile: req.BootFile,
BranchName: req.BranchName,
Description: req.Description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
@@ -830,10 +826,6 @@ func HandleNotebookInfo(task *models.Cloudbrain) error {
task.FlavorCode = result.Flavor
}

if oldStatus != task.Status && task.Status == string(models.ModelArtsRunning) && task.BootFile != "" {
uploadNoteBookFile(task, result)

}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
@@ -844,81 +836,6 @@ func HandleNotebookInfo(task *models.Cloudbrain) error {
return nil
}

func uploadNoteBookFile(task *models.Cloudbrain, result *models.GetNotebook2Result) {
jupyterUrl := result.Url + "?token=" + result.Token

cookies, xsrf := getCookiesAndCsrf(jupyterUrl)
if xsrf == "" {
log.Error("browser jupyterUrl failed:%v", task.DisplayJobName)
} else {

codePath := setting.JobPath + task.JobName + cloudbrain.CodeMountPath
fileContents, err := ioutil.ReadFile(codePath + "/" + task.BootFile)
if err != nil {
log.Error("read jupyter file failed:%v", task.DisplayJobName, err)
}

base64Content := base64.StdEncoding.EncodeToString(fileContents)
client := getRestyClient()
uploadUrl := getJupyterBaseUrl(result.Url) + "api/contents/" + path.Base(task.BootFile)
res, err := client.R().
SetCookies(cookies).
SetHeader("X-XSRFToken", xsrf).
SetBody(map[string]interface{}{
"type": "file",
"format": "base64",
"name": path.Base(task.BootFile),
"path": path.Base(task.BootFile),
"content": base64Content}).
Put(uploadUrl)
if err != nil {
log.Error("upload jupyter file failed:%v", task.DisplayJobName, err)
} else if res.StatusCode() != http.StatusCreated {
log.Error("upload jupyter file failed:%v", task.DisplayJobName, err)
}

}

}

func getJupyterBaseUrl(url string) string {
jupyterUrlLength := len(url)
baseUrl := url[0 : jupyterUrlLength-len(path.Base(url))]
return baseUrl
}

func getCookiesAndCsrf(jupyterUrl string) ([]*http.Cookie, string) {
log.Info("jupyter url:" + jupyterUrl)
var cookies []*http.Cookie
const retryTimes = 10
for i := 0; i < retryTimes; i++ {
res, err := http.Get(jupyterUrl)
if err != nil {
log.Error("browser jupyterUrl failed.", err)
if i == retryTimes-1 {
return cookies, ""
}

} else {
cookies = res.Cookies()
xsrf := ""
for _, cookie := range cookies {
if cookie.Name == "_xsrf" {
xsrf = cookie.Value
break
}

}
if xsrf != "" {
return cookies, xsrf
}

}
}
return cookies, ""

}

func SyncTempStatusJob() {
jobs, err := models.GetCloudBrainTempJobs()
if err != nil {


+ 1
- 0
modules/modelarts_cd/modelarts.go View File

@@ -148,6 +148,7 @@ func GenerateNotebook(ctx *context.Context, req cloudbrain.GenerateModelArtsNote
UpdatedUnix: createTime,
Spec: req.Spec,
BootFile: req.BootFile,
BranchName: req.BranchName,
ModelName: req.ModelName,
ModelVersion: req.ModelVersion,
LabelName: req.LabelName,


+ 198
- 0
modules/notebook/contentManager.go View File

@@ -0,0 +1,198 @@
package notebook

import (
"crypto/tls"
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
"path"
"strings"

"github.com/go-resty/resty/v2"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/setting"

"code.gitea.io/gitea/modules/log"
)

var restyClient *resty.Client

type NotebookApiResponse struct {
Name string `json:"name"`
Path string `json:"path"`
}

type NotebookContent struct {
Url string
Path string
Cookies []*http.Cookie
Xsrf string
PathType string //file directory
Token string
}

func (c *NotebookContent) IsNotebookFileCanBrowser() bool {
if c.Xsrf == "" {
c.SetCookiesAndCsrf()
}
if c.Xsrf == "" {
log.Warn("xsrf is empty, can not broswer url:" + c.Url)
return false
}
return c.IsNoteBookContentsExist()

}

func (c *NotebookContent) SetCookiesAndCsrf() {
log.Info("jupyter url:" + c.Url)
var cookies []*http.Cookie
const retryTimes = 10
url := c.Url
if c.Token != "" {
url = c.Url + "?token=" + c.Token
}
for i := 0; i < retryTimes; i++ {
res, err := http.Get(url)
if err != nil {
log.Error("browser jupyterUrl failed.", err)
if i == retryTimes-1 {
c.Cookies = cookies
}

} else {
cookies = res.Cookies()
xsrf := ""
for _, cookie := range cookies {
if cookie.Name == "_xsrf" {
xsrf = cookie.Value
if len(cookies) > 1 {
break
}

}

}
if xsrf != "" {
c.Cookies = cookies
c.Xsrf = xsrf
}

}
}
c.Cookies = cookies

}

func (c *NotebookContent) IsNoteBookContentsExist() bool {
client := getRestyClient()
uploadUrl := getJupyterBaseUrl(c.Url) + "api/contents/" + c.Path + "?type=" + c.PathType
res, err := client.R().
SetCookies(c.Cookies).
SetHeader("X-XSRFToken", c.Xsrf).
Get(uploadUrl)
if err != nil {
log.Warn("browser url error:"+uploadUrl, err)
return false
}
return res.StatusCode() == http.StatusOK
}

func (c *NotebookContent) UploadNoteBookFile(task *models.Cloudbrain) error {

err := c.MakeNoteBookDir()
if err != nil {
return err
}

codePath := setting.JobPath + task.JobName + cloudbrain.CodeMountPath
fileContents, err := ioutil.ReadFile(codePath + "/" + c.Path)
if err != nil {
log.Error("read jupyter file failed:%v", task.DisplayJobName, err)
}

base64Content := base64.StdEncoding.EncodeToString(fileContents)
client := getRestyClient()
uploadUrl := getJupyterBaseUrl(c.Url) + "api/contents/" + c.Path
res, err := client.R().
SetCookies(c.Cookies).
SetHeader("X-XSRFToken", c.Xsrf).
SetBody(map[string]interface{}{
"type": "file",
"format": "base64",
"name": path.Base(c.Path),
"path": c.Path,
"content": base64Content}).
Put(uploadUrl)
if err != nil {
log.Error("upload jupyter file failed:%v", task.DisplayJobName, err)
return err
} else if res.StatusCode() != http.StatusCreated {
log.Error("upload jupyter file failed:%v, status is %s", task.DisplayJobName, res.Status(), err)
return fmt.Errorf("status:", res.StatusCode())
}
return nil
}

/**
if c.Path is a/b/c.txt
makedir a/b
if c.Path is a/b/c
makedir a/b
*/
func (c *NotebookContent) MakeNoteBookDir() error {
filePaths := strings.Split(c.Path, "/")

for i := 0; i < len(filePaths)-1; i++ {
cTemp := &NotebookContent{
Url: c.Url,
Cookies: c.Cookies,
Path: path.Join(filePaths[0 : i+1]...),
PathType: "directory",
Xsrf: c.Xsrf,
}
if !cTemp.IsNoteBookContentsExist() {

createTempDirUrl := getJupyterBaseUrl(cTemp.Url) + "api/contents/" + cTemp.Path
client := getRestyClient()
var jobResult NotebookApiResponse
res, err := client.R().
SetCookies(c.Cookies).
SetHeader("X-XSRFToken", c.Xsrf).
SetBody(map[string]interface{}{
"type": cTemp.PathType,
"path": cTemp.Path,
}).SetResult(&jobResult).
Put(createTempDirUrl)
if err != nil {
return err
}
if res.StatusCode() != http.StatusCreated {
return fmt.Errorf("status code:" + res.Status())
}

}

}
return nil
}

func getJupyterBaseUrl(url string) string {
jupyterUrlLength := len(url)
baseUrl := url
if strings.HasSuffix(url, "lab") {
baseUrl = url[0 : jupyterUrlLength-len(path.Base(url))]
}

return baseUrl
}

func getRestyClient() *resty.Client {
if restyClient == nil {
restyClient = resty.New()
restyClient.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
}
return restyClient
}

+ 3
- 0
modules/repository/repo.go View File

@@ -139,6 +139,9 @@ func MigrateRepositoryGitData(doer, u *models.User, repo *models.Repository, opt
}

repo.IsMirror = true
if repo.Description == "" {
repo.Description = opts.Description
}
err = models.UpdateRepository(repo, false)
} else {
repo, err = CleanUpMigrateInfo(repo)


+ 33
- 17
modules/setting/setting.go View File

@@ -518,7 +518,7 @@ var (
MaxDatasetNum int
CullIdleTimeout string
CullInterval string
DebugAttachSize int

//benchmark config
IsBenchmarkEnabled bool
@@ -544,6 +544,12 @@ var (
BrainScoreName string
BrainScoreServerHost string

IsSnn4EcosetEnabled bool
Snn4EcosetOwner string
Snn4EcosetName string
Snn4EcosetServerHost string
Snn4AttachmentName string

//blockchain config
BlockChainHost string
CommitValidDate string
@@ -617,14 +623,14 @@ var (
UsageRateBeginTime string
}{}

ClearStrategy= struct {
Enabled bool
ResultSaveDays int
BatchSize int
DebugJobSize int
TrashSaveDays int
Cron string
RunAtStart bool
ClearStrategy = struct {
Enabled bool
ResultSaveDays int
BatchSize int
DebugJobSize int
TrashSaveDays int
Cron string
RunAtStart bool
}{}

C2NetInfos *C2NetSqInfos
@@ -711,6 +717,7 @@ var (

ProjectHealth float64
ProjectHealthIssueCompleteRatio float64
ProjectHealth0IssueCloseRatio float64

TeamHealth float64
TeamHealthContributors float64
@@ -1497,6 +1504,7 @@ func NewContext() {
MaxDatasetNum = sec.Key("MAX_DATASET_NUM").MustInt(5)
CullIdleTimeout = sec.Key("CULL_IDLE_TIMEOUT").MustString("900")
CullInterval = sec.Key("CULL_INTERVAL").MustString("60")
DebugAttachSize = sec.Key("DEBUG_ATTACH_SIZE").MustInt(20)

sec = Cfg.Section("benchmark")
IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false)
@@ -1522,6 +1530,13 @@ func NewContext() {
BrainScoreName = sec.Key("NAME").MustString("")
BrainScoreServerHost = sec.Key("HOST").MustString("")

sec = Cfg.Section("snn4ecoset")
IsSnn4EcosetEnabled = sec.Key("ENABLED").MustBool(false)
Snn4EcosetOwner = sec.Key("OWNER").MustString("")
Snn4EcosetName = sec.Key("NAME").MustString("")
Snn4EcosetServerHost = sec.Key("HOST").MustString("")
Snn4AttachmentName = sec.Key("DATASET").MustString("")

sec = Cfg.Section("blockchain")
BlockChainHost = sec.Key("HOST").MustString("http://192.168.136.66:3302/")
CommitValidDate = sec.Key("COMMIT_VALID_DATE").MustString("2021-01-15")
@@ -1705,16 +1720,16 @@ func getModelartsCDConfig() {
getNotebookFlavorInfos()
}

func getClearStrategy(){
func getClearStrategy() {

sec := Cfg.Section("clear_strategy")
ClearStrategy.Enabled=sec.Key("ENABLED").MustBool(false)
ClearStrategy.ResultSaveDays=sec.Key("RESULT_SAVE_DAYS").MustInt(30)
ClearStrategy.BatchSize=sec.Key("BATCH_SIZE").MustInt(500)
ClearStrategy.DebugJobSize=sec.Key("DEBUG_BATCH_SIZE").MustInt(100)
ClearStrategy.TrashSaveDays=sec.Key("TRASH_SAVE_DAYS").MustInt(90)
ClearStrategy.Cron=sec.Key("CRON").MustString("* 0,30 2-8 * * ?")
ClearStrategy.RunAtStart=sec.Key("RUN_AT_START").MustBool(false)
ClearStrategy.Enabled = sec.Key("ENABLED").MustBool(false)
ClearStrategy.ResultSaveDays = sec.Key("RESULT_SAVE_DAYS").MustInt(30)
ClearStrategy.BatchSize = sec.Key("BATCH_SIZE").MustInt(500)
ClearStrategy.DebugJobSize = sec.Key("DEBUG_BATCH_SIZE").MustInt(100)
ClearStrategy.TrashSaveDays = sec.Key("TRASH_SAVE_DAYS").MustInt(90)
ClearStrategy.Cron = sec.Key("CRON").MustString("* 0,30 2-8 * * ?")
ClearStrategy.RunAtStart = sec.Key("RUN_AT_START").MustBool(false)
}

func getGrampusConfig() {
@@ -1781,6 +1796,7 @@ func SetRadarMapConfig() {
RadarMap.LivenessRelease = sec.Key("liveness_release").MustFloat64(0.4)
RadarMap.ProjectHealth = sec.Key("project_health").MustFloat64(0.1)
RadarMap.ProjectHealthIssueCompleteRatio = sec.Key("project_health_issue_complete_ratio").MustFloat64(100)
RadarMap.ProjectHealth0IssueCloseRatio = sec.Key("project_health_0_issue_close_ratio").MustFloat64(0.0)
RadarMap.TeamHealth = sec.Key("team_health").MustFloat64(0.1)
RadarMap.TeamHealthContributors = sec.Key("team_health_contributors").MustFloat64(0.2)
RadarMap.TeamHealthKeyContributors = sec.Key("team_health_key_contributors").MustFloat64(0.6)


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

@@ -391,3 +391,19 @@ func GetPartInfos(objectName string, uploadID string) (string, error) {

return chunks, nil
}

func IsObjectExist4Minio(bucket, objectName string) (bool, error) {
_, core, err := getClients()
if err != nil {
log.Error("getClients failed:", err.Error())
return false, err
}

_, err = core.StatObject(bucket, objectName, miniov6.StatObjectOptions{})
if err != nil {
log.Error("GetObjectMetadata error.%v", err)
return false, err
}

return true, nil
}

+ 33
- 4
modules/storage/obs.go View File

@@ -614,7 +614,7 @@ func ObsCreateObject(path string) error {
return nil
}

func GetObsLogFileName(prefix string) (string, error) {
func GetObsLogFileName(prefix string) ([]FileInfo, error) {
input := &obs.ListObjectsInput{}
input.Bucket = setting.Bucket
input.Prefix = prefix
@@ -622,10 +622,39 @@ func GetObsLogFileName(prefix string) (string, error) {
output, err := ObsCli.ListObjects(input)
if err != nil {
log.Error("PutObject failed:", err.Error())
return "", err
return nil, err
}
if output == nil || len(output.Contents) == 0 {
return "", errors.New("obs log files not exist")
return nil, errors.New("obs log files not exist")
}
fileInfos := make([]FileInfo, 0)
for _, val := range output.Contents {
//result[num] = c.Key
if strings.HasSuffix(val.Key, ".log") {
log.Info("log fileName=" + val.Key)
fileInfo := FileInfo{
ModTime: val.LastModified.Local().Format("2006-01-02 15:04:05"),
FileName: val.Key[len(prefix)-3:], //加上 job
Size: val.Size,
IsDir: false,
ParenDir: prefix[0 : len(prefix)-3],
}
fileInfos = append(fileInfos, fileInfo)
}

}
return fileInfos, nil
}

func IsObjectExist4Obs(bucket, key string) (bool, error) {

_, err := ObsCli.GetObjectMetadata(&obs.GetObjectMetadataInput{
Bucket: bucket,
Key: key,
})
if err != nil {
log.Error("GetObjectMetadata error.%v", err)
return false, err
}
return output.Contents[0].Key, nil
return true, nil
}

+ 28
- 27
modules/structs/cloudbrain.go View File

@@ -47,36 +47,37 @@ type CreateFileNotebookJobOption struct {
BranchName string `json:"branch_name" binding:"Required"`
OwnerName string `json:"owner_name" binding:"Required"`
ProjectName string `json:"project_name" binding:"Required"`
JobId string `json:"job_id"`
}

type Cloudbrain struct {
ID int64 `json:"id"`
JobID string `json:"job_id"`
JobType string `json:"job_type"`
Type int `json:"type"`
DisplayJobName string `json:"display_job_name"`
Status string `json:"status"`
CreatedUnix int64 `json:"created_unix"`
RepoID int64 `json:"repo_id"`
Duration int64 `json:"duration"` //运行时长 单位秒
TrainJobDuration string `json:"train_job_duration"`
ImageID string `json:"image_id"` //grampus image_id
Image string `json:"image"`
Uuid string `json:"uuid"` //数据集id
DatasetName string `json:"dataset_name"`
ComputeResource string `json:"compute_resource"` //计算资源,例如npu
AiCenter string `json:"ai_center"` //grampus ai center: center_id+center_name
BranchName string `json:"branch_name"` //分支名称
Parameters string `json:"parameters"` //传给modelarts的param参数
BootFile string `json:"boot_file"` //启动文件
Description string `json:"description"` //描述
ModelName string `json:"model_name"` //模型名称
ModelVersion string `json:"model_version"` //模型版本
CkptName string `json:"ckpt_name"` //权重文件名称
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
Spec *SpecificationShow `json:"spec"`
ID int64 `json:"id"`
JobID string `json:"job_id"`
JobType string `json:"job_type"`
Type int `json:"type"`
DisplayJobName string `json:"display_job_name"`
Status string `json:"status"`
CreatedUnix int64 `json:"created_unix"`
RepoID int64 `json:"repo_id"`
Duration int64 `json:"duration"` //运行时长 单位秒
TrainJobDuration string `json:"train_job_duration"`
ImageID string `json:"image_id"` //grampus image_id
Image string `json:"image"`
Uuid string `json:"uuid"` //数据集id
DatasetName string `json:"dataset_name"`
ComputeResource string `json:"compute_resource"` //计算资源,例如npu
AiCenter string `json:"ai_center"` //grampus ai center: center_id+center_name
BranchName string `json:"branch_name"` //分支名称
Parameters string `json:"parameters"` //传给modelarts的param参数
BootFile string `json:"boot_file"` //启动文件
Description string `json:"description"` //描述
ModelName string `json:"model_name"` //模型名称
ModelVersion string `json:"model_version"` //模型版本
CkptName string `json:"ckpt_name"` //权重文件名称
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
VersionName string `json:"version_name"`
Spec *SpecificationShow `json:"spec"`
}

type SpecificationShow struct {


+ 10
- 2
modules/templates/helper.go View File

@@ -98,11 +98,16 @@ func NewFuncMap() []template.FuncMap {
"AllowedReactions": func() []string {
return setting.UI.Reactions
},
"DebugAttachSize": func() int {
return setting.DebugAttachSize * 1000 * 1000 * 1000
},
"AvatarLink": models.AvatarLink,
"Safe": Safe,
"SafeJS": SafeJS,
"Str2html": Str2html,
"subOne": subOne,
"addOne": addOne,
"TimeStampNow": timeutil.TimeStampNow,
"TimeSince": timeutil.TimeSince,
"TimeSinceUnix": timeutil.TimeSinceUnix,
"TimeSinceUnix1": timeutil.TimeSinceUnix1,
@@ -153,7 +158,7 @@ func NewFuncMap() []template.FuncMap {
"EscapePound": func(str string) string {
return strings.NewReplacer("%", "%25", "#", "%23", " ", "%20", "?", "%3F").Replace(str)
},
"IpynbBool":func(str string) bool{
"IpynbBool": func(str string) bool {
return strings.Contains(str, ".ipynb")
},
"nl2br": func(text string) template.HTML {
@@ -363,6 +368,7 @@ func NewTextFuncMap() []texttmpl.FuncMap {
"AppDomain": func() string {
return setting.Domain
},
"TimeStampNow": timeutil.TimeStampNow,
"TimeSince": timeutil.TimeSince,
"TimeSinceUnix": timeutil.TimeSinceUnix,
"TimeSinceUnix1": timeutil.TimeSinceUnix1,
@@ -470,7 +476,9 @@ func Str2html(raw string) template.HTML {
func subOne(length int) int {
return length - 1
}

func addOne(length int64) int64 {
return length + 1
}
// Escape escapes a HTML string
func Escape(raw string) string {
return html.EscapeString(raw)


+ 28
- 4
options/locale/locale_en-US.ini View File

@@ -406,6 +406,8 @@ sspi_auth_failed = SSPI authentication failed
change_email = Change email
change_email_address = Change email address
new_email_address = New email address
openi_community_really_awesome = OpenI, Really Awesome!

[phone]
format_err=The format of phone number is wrong.
query_err=Fail to query phone number, please try again later.
@@ -577,6 +579,7 @@ static.CloudBrainTaskNum=CloudBrain Task Count
static.CloudBrainRunTime=CloudBrain Run Time
static.CommitDatasetNum=Commit Dataset Count
static.CommitModelCount=Commit Model Count
static.ModelConvertCount=Model Convert Count
static.UserIndex=Normalized user index
static.UserIndexPrimitive=User Index
static.countdate=Count Date
@@ -1060,8 +1063,12 @@ model_rename=Duplicate model name, please modify model name.

notebook_file_not_exist=Notebook file does not exist.
notebook_select_wrong=Please select a Notebook(.ipynb) file first.
notebook_path_too_long=The total length of selected file or files path exceed 255 characters, please select a shorter path file or change the file path.
notebook_branch_name_too_long=The total length of branch or branches name exceed 255 characters, please select a file in other branch.
notebook_file_no_right=You have no right to access the Notebook(.ipynb) file.
notebook_repo_conflict=The files in different branches of the same repository can not run together.
debug_again_fail=Fail to restart debug task, please try again later.
debug_again_fail_forever=The task was scheduled failed last time, can not restart.

date=Date
repo_add=Project Increment
@@ -1079,6 +1086,7 @@ delete=Delete
more=More
gpu_type_all=All
model_download=Model Download
all_result_download=All result download
submit_image=Submit Image
modify_image=Modify Image
image_exist=Image name has been used, please use a new one.
@@ -1091,8 +1099,8 @@ image_delete_fail=Failed to delete image, please try again later.
image_overwrite=You had submitted the same name image before, are you sure to overwrite the original image?
download=Download
score=Score
wait_count_start = There are currently
wait_count_end = tasks queued
wait_count_start = Your current queue position is
wait_count_end =
file_limit_100 = Display up to 100 files or folders in a single directory
images.name = Image Tag
images.name_placerholder = Please enter the image name
@@ -1257,6 +1265,13 @@ modelarts.fullscreen_log_file = View in full screen
modelarts.exit_full_screen = Exit fullscreen
modelarts.no_node_right = The value of 'Amount of Compute Node' is wrong, you have no right to use the current value of 'Amount of Compute Node'.

scrolled_logs_top = You have scrolled to the top of the log
scrolled_logs_top_pls_retry = You have scrolled to the top of the log, please try again later!
scrolled_logs_bottom = You have scrolled to the bottom of the log
scrolled_logs_bottom_pls_retry = You have scrolled to the bottom of the log, please try again later!

canceled_operation = You have canceled the operation
successfully_deleted = Successfully deleted

debug_task_not_created = Debug task has not been created
train_task_not_created = Train task has not been created
@@ -1345,6 +1360,7 @@ modelconvert.inputshapeerror=Format input error, please input such as: 1,1,32,32
modelconvert.manage.create_error1=A model transformation task with the same name already exists.
modelconvert.manage.create_error2=Only one running model transformation task can be created.
modelconvert.manage.model_not_exist=The model in the task does not exist or has been deleted.
modelconvert.manage.model_file_not_exist=The model file in the task does not exist or has been deleted.
modelconvert.manage.no_operate_right=You have no right to do the operation.

debug.manage.model_not_exist=The model in the task does not exist or has been deleted, please create a new debug job.
@@ -1470,7 +1486,7 @@ blame = Blame
normal_view = Normal View
line = line
lines = lines
notebook_open = Open in Notebook
notebook_open = Run Online

editor.new_file = New File
editor.upload_file = Upload File
@@ -2755,6 +2771,10 @@ repos.pr=PR
repos.commit=Commit
repos.closedIssues=Closed Issue
repos.contributor=Contributor
repos.numDataset=Dataset File
repos.numCloudbrain=Cloudbrain Task
repos.numModel=Model
repos.numModelConvert=Model Convert Task
repos.yes=Yes
repos.no=No

@@ -3127,6 +3147,7 @@ task_gpudebugjob=`created CPU/GPU type debugging task <a href="%s/cloudbrain/%s"
task_npudebugjob=`created NPU type debugging task <a href="%s/modelarts/notebook/%s">%s</a>`
task_c2net_gpudebugjob=`created CPU/GPU type debugging task <a href="%s/grampus/notebook/%s">%s</a>`
task_c2net_npudebugjob=`created NPU type debugging task <a href="%s/grampus/notebook/%s">%s</a>`
task_c2ent_gcudebugjob=`created GCU type debugging task <a href="%s/grampus/notebook/%s">%s</a>`
task_nputrainjob=`created NPU training task <a href="%s/modelarts/train-job/%s">%s</a>`
task_inferencejob=`created reasoning task <a href="%s/modelarts/inference-job/%s">%s</a>`
task_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>`
@@ -3287,6 +3308,7 @@ point_hr = Point/hr
DEBUG = DEBUG
SNN4IMAGENET = BENCHMARK
BRAINSCORE = BENCHMARK
SNN4ECOSET = BENCHMARK
MODELSAFETY = BENCHMARK
TRAIN = TRAIN
INFERENCE = INFERENCE
@@ -3300,13 +3322,15 @@ Stopped_failed=Fail to stop the job, please try again later.
Stopped_success_update_status_fail=Succeed in stopping th job, but failed to update the job status and duration time.
load_code_failed=Fail to load code, please check if the right branch is selected.

error.debug_datasetsize = The size of dataset exceeds limitation (%dGB)
error.dataset_select = dataset select error:the count exceed the limit or has same name
error.partial_datasets_not_available = There are non-existent or deleted files in the selected dataset file, please select again
new_train_gpu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_debug_gpu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_debug_gpu_tooltips1 = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the <strong style="color:#010101">%s</strong>.
new_train_npu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_infer_gpu_tooltips = The dataset is stored in <strong style="color:#010101">%s</strong>, the model file is stored in <strong style="color:#010101">%s</strong>, please store the inference output in <strong style="color:#010101">%s</strong> for subsequent downloads.
code_obs_address = Code OBS address
code_obs_address = Code OBS address

[points]
points = points


+ 30
- 6
options/locale/locale_zh-CN.ini View File

@@ -73,7 +73,7 @@ your_starred=已点赞
your_settings=设置
invite_friends=邀请好友
your_friend=您的好友
invite_you_to_join_the_OpenI_AI_Collaboration_Platform_and_enjoy_abundant_free_computing_resources=邀请您加入启智社区AI协作平台,畅享充沛的免费算力资源!
invite_you_to_join_the_OpenI_AI_Collaboration_Platform_and_enjoy_abundant_free_computing_resources=邀请您加入启智社区AI协作平台,畅享充沛的普惠算力资源!
recommender=推荐人

all=所有
@@ -409,6 +409,8 @@ sspi_auth_failed=SSPI 认证失败
change_email=修改邮箱
change_email_address=修改邮箱地址
new_email_address=新邮箱地址
openi_community_really_awesome=启智社区 确实给力

[phone]
format_err=手机号格式错误。
query_err=查询手机号失败,请稍后再试。
@@ -581,6 +583,7 @@ static.CloudBrainTaskNum=云脑任务数
static.CloudBrainRunTime=云脑运行时间(小时)
static.CommitDatasetNum=上传(提交)数据集文件数
static.CommitModelCount=提交模型数
static.ModelConvertCount=模型转换数
static.UserIndex=归一化用户指数
static.UserIndexPrimitive=用户指数
static.countdate=系统统计时间
@@ -1059,8 +1062,12 @@ model_rename=模型名称重复,请修改模型名称

notebook_file_not_exist=Notebook文件不存在。
notebook_select_wrong=请先选择Notebook(.ipynb)文件。
notebook_path_too_long=选择的一个或多个Notebook文件路径总长度超过255个字符,请选择路径较短的文件或调整文件路径。
notebook_branch_name_too_long=选择的一个或多个Notebook文件分支名总长度超过255个字符,请选择其他分支的文件。
notebook_file_no_right=您没有这个Notebook文件的读权限。
notebook_repo_conflict=同一个仓库的不同分支文件不能同时运行。
debug_again_fail=再次调试失败,请稍后再试。
debug_again_fail_forever=这个任务之前没有调度成功,不能再次调试。

date=日期
repo_add=新增项目
@@ -1078,6 +1085,7 @@ delete=删除
more=更多
gpu_type_all=全部
model_download=结果下载
all_result_download=全部结果下载
submit_image=提交镜像
modify_image=修改镜像
image_exist=镜像Tag已被使用,请修改镜像Tag。
@@ -1090,8 +1098,8 @@ image_delete_fail=删除镜像失败,请稍后再试。
image_overwrite=您已经提交过相同名称的镜像,您确定要覆盖原来提交的镜像吗?
download=模型下载
score=评分
wait_count_start = 当前有
wait_count_end = 个任务正在排队
wait_count_start = 您当前排队位置是第
wait_count_end =
file_limit_100 = 单目录下最多显示100个文件或文件夹
images.name = 镜像Tag
images.name_placerholder = 请输入镜像Tag
@@ -1269,6 +1277,13 @@ modelarts.fullscreen_log_file=全屏查看
modelarts.exit_full_screen=退出全屏
modelarts.no_node_right = 计算节点数的值配置错误,您没有权限使用当前配置的计算节点数。

scrolled_logs_top = 您已翻阅至日志顶部
scrolled_logs_top_pls_retry = 您已翻阅至日志顶部,请稍后再试!
scrolled_logs_bottom = 您已翻阅至日志底部
scrolled_logs_bottom_pls_retry = 您已翻阅至日志底部,请稍后再试!

canceled_operation = 您已取消操作
successfully_deleted = 删除成功

debug_task_not_created = 未创建过调试任务
train_task_not_created = 未创建过训练任务
@@ -1359,6 +1374,7 @@ modelconvert.modelfileempty=请选择模型文件。
modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。
modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。
modelconvert.manage.model_not_exist=任务中选择的模型不存在或者已被删除。
modelconvert.manage.model_file_not_exist=任务中选择的模型文件不存在或者已被删除。
modelconvert.manage.no_operate_right=您没有操作权限。


@@ -1488,7 +1504,7 @@ normal_view=普通视图
line=行
lines=行

notebook_open = 在Notebook中打开
notebook_open = 在线运行

editor.new_file=新建文件
editor.upload_file=上传文件
@@ -1672,7 +1688,7 @@ issues.action_assignee_no_select=未指派
issues.opened_by=由 <a href="%[2]s">%[3]s</a> 于 %[1]s创建
pulls.merged_by=由 <a href="%[2]s">%[3]s</a> 于 %[1]s 合并
pulls.merged_by_fake=由 %[2]s 于 %[1]s 合并
issues.closed_by=按 <a href="%[2]s">%[3]s</a> 关闭%[1]s
issues.closed_by=由 <a href="%[2]s">%[3]s</a> 创建,被关闭于 %[1]s
issues.opened_by_fake=由 %[2]s 于 %[1]s创建
issues.closed_by_fake=通过 %[2]s 关闭 %[1]s
issues.previous=上一页
@@ -2773,6 +2789,11 @@ repos.pr=PR数
repos.commit=Commit数
repos.closedIssues=已解决任务数
repos.contributor=贡献者数
repos.numDataset=数据集文件数
repos.numCloudbrain=云脑任务数
repos.numModel=模型数
repos.numModelConvert=转换任务数

repos.yes=是
repos.no=否

@@ -3145,6 +3166,7 @@ task_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/cloudbrain/%s">
task_npudebugjob=`创建了NPU类型调试任务 <a href="%s/modelarts/notebook/%s">%s</a>`
task_c2net_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/grampus/notebook/%s">%s</a>`
task_c2net_npudebugjob=`创建了NPU类型调试任务 <a href="%s/grampus/notebook/%s">%s</a>`
task_c2ent_gcudebugjob=`创建了GCU类型调试任务 <a href="%s/grampus/notebook/%s">%s</a>`
task_nputrainjob=`创建了NPU类型训练任务 <a href="%s/modelarts/train-job/%s">%s</a>`
task_inferencejob=`创建了推理任务 <a href="%s/modelarts/inference-job/%s">%s</a>`
task_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>`
@@ -3307,6 +3329,7 @@ point_hr = 积分/时
DEBUG = 调试任务
SNN4IMAGENET = 评测任务
BRAINSCORE = 评测任务
SNN4ECOSET = 评测任务
MODELSAFETY = 评测任务
TRAIN = 训练任务
INFERENCE = 推理任务
@@ -3320,8 +3343,9 @@ Stopped_failed=任务停止失败,请稍后再试。
Stopped_success_update_status_fail=任务停止成功,状态及运行时间更新失败。
load_code_failed=代码加载失败,请确认选择了正确的分支。

error.debug_datasetsize = 数据集大小超过限制(%dGB)
error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集
error.partial_datasets_not_available = 选择的数据集文件中有不存在或已删除的文件,请重新选择
new_train_gpu_tooltips = 训练脚本存储在 <strong style="color:#010101">%s</strong> 中,数据集存储在 <strong style="color:#010101">%s</strong> 中,预训练模型存放在运行参数 <strong style="color:#010101">%s</strong> 中,训练输出请存储在 <strong style="color:#010101">%s</strong> 中以供后续下载。
new_debug_gpu_tooltips = 项目代码存储在 <strong style="color:#010101">%s</strong> 中,数据集存储在 <strong style="color:#010101">%s</strong> 中,选择的模型存储在 <strong style="color:#010101">%s</strong> 中,调试输出请存储在 <strong style="color:#010101">%s</strong> 中以供后续下载。
new_debug_gpu_tooltips1 = 项目代码存储在 <strong style="color:#010101">%s</strong> 中,数据集存储在 <strong style="color:#010101">%s</strong> 中,选择的模型存储在 <strong style="color:#010101">%s</strong> 中。


+ 34
- 65
package-lock.json View File

@@ -1982,28 +1982,6 @@
"object.assign": "^4.1.0"
}
},
"babel-polyfill": {
"version": "6.26.0",
"resolved": "https://registry.npm.taobao.org/babel-polyfill/download/babel-polyfill-6.26.0.tgz",
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
"requires": {
"babel-runtime": "^6.26.0",
"core-js": "^2.5.0",
"regenerator-runtime": "^0.10.5"
},
"dependencies": {
"core-js": {
"version": "2.6.12",
"resolved": "https://registry.npm.taobao.org/core-js/download/core-js-2.6.12.tgz?cache=0&sync_timestamp=1611040749668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-2.6.12.tgz",
"integrity": "sha1-2TM9+nsGXjR8xWgiGdb2kIWcwuw="
},
"regenerator-runtime": {
"version": "0.10.5",
"resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.10.5.tgz",
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg="
}
}
},
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -2194,9 +2172,9 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
"blueimp-md5": {
"version": "2.18.0",
"resolved": "https://registry.npm.taobao.org/blueimp-md5/download/blueimp-md5-2.18.0.tgz",
"integrity": "sha1-EVK+EzXwxrORHtnjbbVPPmrFKTU="
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
"integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="
},
"bn.js": {
"version": "5.1.1",
@@ -3536,6 +3514,11 @@
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
"integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI="
},
"dayjs": {
"version": "1.10.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
"integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
},
"de-indent": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
@@ -4152,25 +4135,29 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"esdk-obs-browserjs": {
"version": "3.20.7",
"resolved": "https://registry.npm.taobao.org/esdk-obs-browserjs/download/esdk-obs-browserjs-3.20.7.tgz",
"integrity": "sha1-vhziRlKEhW3PgZPl0DyX68bJI0s=",
"version": "3.22.3",
"resolved": "https://registry.npmjs.org/esdk-obs-browserjs/-/esdk-obs-browserjs-3.22.3.tgz",
"integrity": "sha512-MATZXp0FwjPtKG9tpdfURa3koUarR/ev+tbO0oUKgj0GRt0798ZxmfCvYvRpgNst4w1ht4E79ikD4H40UYLgPA==",
"requires": {
"axios": "^0.19.0",
"babel-polyfill": "^6.26.0",
"blueimp-md5": "^2.10.0",
"js-base64": "^2.3.2",
"jssha": "^2.3.1",
"urijs": "^1.19.1"
"axios": "^0.26.1",
"blueimp-md5": "^2.18.0",
"js-base64": "^3.7.1",
"jssha": "^3.2.0",
"urijs": "^1.19.7"
},
"dependencies": {
"axios": {
"version": "0.19.2",
"resolved": "https://registry.npm.taobao.org/axios/download/axios-0.19.2.tgz?cache=0&sync_timestamp=1608609215811&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz",
"integrity": "sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc=",
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"requires": {
"follow-redirects": "1.5.10"
"follow-redirects": "^1.14.8"
}
},
"js-base64": {
"version": "3.7.3",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.3.tgz",
"integrity": "sha512-PAr6Xg2jvd7MCR6Ld9Jg3BmTcjYsHEBx1VlwEwULb/qowPf5VD9kEMagj23Gm7JRnSvE/Da/57nChZjnvL8v6A=="
}
}
},
@@ -5382,27 +5369,9 @@
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz?cache=0&sync_timestamp=1611606737937&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz",
"integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=",
"requires": {
"debug": "=3.1.0"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.1.0.tgz",
"integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"fomantic-ui": {
"version": "2.8.4",
@@ -7884,9 +7853,9 @@
}
},
"jssha": {
"version": "2.4.2",
"resolved": "https://registry.npm.taobao.org/jssha/download/jssha-2.4.2.tgz",
"integrity": "sha1-2VCwlWNJKL1rK9odQtqaOnYtZek="
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.0.tgz",
"integrity": "sha512-w9OtT4ALL+fbbwG3gw7erAO0jvS5nfvrukGPMWIAoea359B26ALXGpzy4YJSp9yGnpUvuvOw1nSjSoHDfWSr1w=="
},
"just-debounce": {
"version": "1.0.0",
@@ -14400,9 +14369,9 @@
}
},
"urijs": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.6.tgz",
"integrity": "sha512-eSXsXZ2jLvGWeLYlQA3Gh36BcjF+0amo92+wHPyN1mdR8Nxf75fuEuYTd9c0a+m/vhCjRK0ESlE9YNLW+E1VEw=="
"version": "1.19.11",
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz",
"integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="
},
"urix": {
"version": "0.1.0",


+ 8
- 5
public/home/home.js View File

@@ -243,11 +243,12 @@ document.onreadystatechange = function () {
html += recordPrefix + actionName;
html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>"
}
else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30" || record.OpType == "31" || record.OpType == "32" || record.OpType == "33"){
else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30"
|| record.OpType == "31" || record.OpType == "32" || record.OpType == "33"){
html += recordPrefix + actionName;
html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>"
}
else if(record.OpType == "25" || record.OpType == "29" || record.OpType == "39" || record.OpType == "40"){
else if(record.OpType == "25" || record.OpType == "29" || record.OpType == "39" || record.OpType == "40" || record.OpType == "41"){
html += recordPrefix + actionName;
html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>"
}
@@ -294,7 +295,7 @@ function getTaskLink(record){
re = re + "/cloudbrain/train-job/" + record.Content;
}else if(record.OpType == 32 || record.OpType == 33){
re = re + "/grampus/train-job/" + record.Content;
}else if(record.OpType == 39 || record.OpType == 40){
}else if(record.OpType == 39 || record.OpType == 40 || record.OpType == 41){
re = re + "/grampus/notebook/" + record.Content;
}
@@ -453,9 +454,10 @@ var actionNameZH={
"33":"创建了CPU/GPU类型训练任务",
"35":"创建的数据集 {dataset} 被设置为推荐数据集",
"36":"提交了镜像 {image}",
"37": "提交的镜像 {image} 被设置为推荐镜像",
"37":"提交的镜像 {image} 被设置为推荐镜像",
"39":"创建了CPU/GPU类型调试任务",
"40":"创建了NPU类型调试任务",
"41":"创建了GCU类型调试任务",
};

var actionNameEN={
@@ -486,9 +488,10 @@ var actionNameEN={
"33":" created CPU/GPU type training task",
"35":" created dataset {dataset} was set as recommended dataset",
"36":"committed image {image}",
"37": "committed image {image} was set as recommended image",
"37":"committed image {image} was set as recommended image",
"39":" created CPU/GPU type debugging task ",
"40":" created NPU type debugging task ",
"41":" created GCU type debugging task ",
};

var repoAndOrgZH={


BIN
public/img/login_bg_default.png View File

Before After
Width: 1200  |  Height: 938  |  Size: 142 kB

+ 1
- 1
routers/admin/cloudbrains.go View File

@@ -53,7 +53,7 @@ func CloudBrains(ctx *context.Context) {
var jobTypes []string
jobTypeNot := false
if jobType == string(models.JobTypeBenchmark) {
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet))
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeSnn4Ecoset))
} else if jobType != "all" && jobType != "" {
jobTypes = append(jobTypes, jobType)
}


+ 5
- 1
routers/api/v1/api.go View File

@@ -549,6 +549,8 @@ func RegisterRoutes(m *macaron.Macaron) {

}, reqToken())

m.Get("/compute-nodes", reqToken(), user.GetComputeNodes)

// Notifications
m.Group("/notifications", func() {
m.Combo("").
@@ -745,7 +747,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/file_notebook", func() {
m.Get("", repo.GetFileNoteBookInfo)
m.Post("/create", reqToken(), reqWeChat(), bind(api.CreateFileNotebookJobOption{}), repo.CreateFileNoteBook)
m.Post("/status", reqToken(), bind(api.CreateFileNotebookJobOption{}), repo.FileNoteBookStatus)
})

m.Group("/repos", func() {
@@ -1024,6 +1026,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/query_model_byName", repo.QueryModelByName)
m.Get("/query_model_for_predict", repo.QueryModelListForPredict)
m.Get("/query_modelfile_for_predict", repo.QueryModelFileForPredict)
m.Get("/query_train_job", repo.QueryTrainJobList)
m.Get("/query_train_job_version", repo.QueryTrainJobVersionList)
m.Get("/query_train_model", repo.QueryTrainModelList)
m.Post("/create_model_convert", repo.CreateModelConvert)
m.Post("/convert_stop", repo.StopModelConvert)


+ 45
- 0
routers/api/v1/repo/attachments.go View File

@@ -1,22 +1,67 @@
package repo

import (
"net/http"

"code.gitea.io/gitea/modules/log"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
routeRepo "code.gitea.io/gitea/routers/repo"
)

func GetSuccessChunks(ctx *context.APIContext) {
if errStr := checkDatasetPermission(ctx); errStr != "" {
ctx.JSON(http.StatusForbidden, ctx.Tr(errStr))
}

routeRepo.GetSuccessChunks(ctx.Context)
}

func checkDatasetPermission(ctx *context.APIContext) string {
datasetId := ctx.QueryInt64("dataset_id")

dataset, err := models.GetDatasetByID(datasetId)
if err != nil {
log.Warn("can not find dataset", err)

return "dataset.query_dataset_fail"
}
repo, err := models.GetRepositoryByID(dataset.RepoID)
if err != nil {
log.Warn("can not find repo", err)
return "dataset.query_dataset_fail"
}

permission, err := models.GetUserRepoPermission(repo, ctx.User)
if err != nil {
log.Warn("can not find repo permission for user", err)
return "dataset.query_dataset_fail"
}
if !permission.CanWrite(models.UnitTypeDatasets) {

return "error.no_right"
}
return ""
}

func NewMultipart(ctx *context.APIContext) {
if errStr := checkDatasetPermission(ctx); errStr != "" {
ctx.JSON(http.StatusForbidden, ctx.Tr(errStr))
}
routeRepo.NewMultipart(ctx.Context)
}
func GetMultipartUploadUrl(ctx *context.APIContext) {
if errStr := checkDatasetPermission(ctx); errStr != "" {
ctx.JSON(http.StatusForbidden, ctx.Tr(errStr))
}
routeRepo.GetMultipartUploadUrl(ctx.Context)
}

func CompleteMultipart(ctx *context.APIContext) {
if errStr := checkDatasetPermission(ctx); errStr != "" {
ctx.JSON(http.StatusForbidden, ctx.Tr(errStr))
}
routeRepo.CompleteMultipart(ctx.Context)

}


+ 3
- 0
routers/api/v1/repo/cloudbrain.go View File

@@ -110,6 +110,9 @@ func GeneralCloudBrainJobStop(ctx *context.APIContext) {
func CreateFileNoteBook(ctx *context.APIContext, option api.CreateFileNotebookJobOption) {
cloudbrainTask.FileNotebookCreate(ctx.Context, option)
}
func FileNoteBookStatus(ctx *context.APIContext, option api.CreateFileNotebookJobOption) {
cloudbrainTask.FileNotebookStatus(ctx.Context, option)
}

func GetFileNoteBookInfo(ctx *context.APIContext) {
//image description spec description waiting count


+ 48
- 18
routers/api/v1/repo/cloudbrain_dashboard.go View File

@@ -623,7 +623,7 @@ func GetAllCloudbrainsPeriodDistribution(ctx *context.Context) {
}

jobTypeList := []string{string(models.JobTypeDebug), string(models.JobTypeTrain), string(models.JobTypeInference), string(models.JobTypeBenchmark),
string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)}
string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeSnn4Ecoset)}
for _, v := range jobTypeList {
if _, ok := cloudOneJobTypeRes[v]; !ok {
cloudOneJobTypeRes[v] = 0
@@ -645,7 +645,7 @@ func GetAllCloudbrainsPeriodDistribution(ctx *context.Context) {
}
}

ComputeResourceList := []string{"CPU/GPU", "NPU"}
ComputeResourceList := []string{"CPU/GPU", "NPU", "GCU"}
for _, v := range ComputeResourceList {
if _, ok := cloudBrainComputeResource[v]; !ok {
cloudBrainComputeResource[v] = 0
@@ -687,7 +687,6 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
return
}
recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
endTime := time.Now()
listType := ctx.Query("listType")
jobType := ctx.Query("jobType")
jobStatus := ctx.Query("jobStatus")
@@ -695,6 +694,33 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
aiCenter := ctx.Query("aiCenter")
needDeleteInfo := ctx.Query("needDeleteInfo")

accCardType := ctx.Query("accCardType")
accCardsNum := ctx.QueryInt("accCardsNum")
workServerNumber := ctx.QueryInt("workServerNumber")
beginTimeStr := ctx.QueryTrim("beginTime")
endTimeStr := ctx.QueryTrim("endTime")
var beginTimeUnix int64
var endTimeUnix int64
if beginTimeStr == "" || endTimeStr == "" {
beginTimeUnix = int64(recordBeginTime)
endTimeUnix = time.Now().Unix()
} else {
beginTime, err := time.ParseInLocation("2006-01-02T15:04:05", beginTimeStr, time.Local)
if err != nil {
log.Error("Can not ParseInLocation.", err)
ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
return
}
beginTimeUnix = beginTime.Unix()
endTime, err := time.ParseInLocation("2006-01-02T15:04:05", endTimeStr, time.Local)
if err != nil {
log.Error("Can not ParseInLocation.", err)
ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
return
}
endTimeUnix = endTime.Unix()
}

if cloudBrainType == models.TypeCloudBrainOne && aiCenter == models.AICenterOfCloudBrainOne {
aiCenter = ""
}
@@ -730,7 +756,7 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
var jobTypes []string
jobTypeNot := false
if jobType == string(models.JobTypeBenchmark) {
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet))
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeSnn4Ecoset))
} else if jobType != "all" && jobType != "" {
jobTypes = append(jobTypes, jobType)
}
@@ -753,18 +779,21 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
Page: page,
PageSize: pageSize,
},
Keyword: keyword,
Type: cloudBrainType,
ComputeResource: listType,
JobTypeNot: jobTypeNot,
JobStatusNot: jobStatusNot,
JobStatus: jobStatuses,
JobTypes: jobTypes,
NeedRepoInfo: true,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
AiCenter: aiCenter,
NeedDeleteInfo: needDeleteInfo,
Keyword: keyword,
Type: cloudBrainType,
ComputeResource: listType,
JobTypeNot: jobTypeNot,
JobStatusNot: jobStatusNot,
JobStatus: jobStatuses,
JobTypes: jobTypes,
NeedRepoInfo: true,
BeginTimeUnix: beginTimeUnix,
EndTimeUnix: endTimeUnix,
AiCenter: aiCenter,
NeedDeleteInfo: needDeleteInfo,
AccCardType: accCardType,
AccCardsNum: accCardsNum,
WorkServerNumber: workServerNumber,
})
if err != nil {
ctx.ServerError("Get job failed:", err)
@@ -1039,7 +1068,7 @@ func getCloudbrainCount(beginTime time.Time, endTime time.Time, cloudbrains []*m
}
}

ComputeResourceList := []string{"CPU/GPU", "NPU"}
ComputeResourceList := []string{"CPU/GPU", "NPU", "GCU"}
for _, v := range ComputeResourceList {
if _, ok := cloudBrainComputeResource[v]; !ok {
cloudBrainComputeResource[v] = 0
@@ -1231,8 +1260,8 @@ func DownloadCloudBrainBoard(ctx *context.Context) {
Type: models.TypeCloudBrainAll,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
AccCardsNum: models.AccCardsNumAll,
})
log.Info("totalcountisis:", total)

if err != nil {
log.Warn("Can not get cloud brain info", err)
@@ -1261,6 +1290,7 @@ func DownloadCloudBrainBoard(ctx *context.Context) {
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
NeedRepoInfo: true,
AccCardsNum: models.AccCardsNumAll,
})
if err != nil {
log.Warn("Can not get cloud brain info", err)


+ 32
- 0
routers/api/v1/repo/modelmanage.go View File

@@ -4,8 +4,10 @@ import (
"net/http"

"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/storage"
api "code.gitea.io/gitea/modules/structs"
routerRepo "code.gitea.io/gitea/routers/repo"
)

@@ -54,6 +56,21 @@ func QueryModelListForPredict(ctx *context.APIContext) {
routerRepo.QueryModelListForPredict(ctx.Context)
}

func QueryTrainJobList(ctx *context.APIContext) {
result, err := routerRepo.QueryTrainJobListApi(ctx.Context)
if err != nil {
log.Info("query error." + err.Error())
ctx.JSON(http.StatusOK, nil)
} else {
re := make([]*api.Cloudbrain, 0)
for _, task := range result {
conRe := convert.ToCloudBrain(task)
re = append(re, conRe)
}
ctx.JSON(http.StatusOK, re)
}
}

func QueryTrainModelList(ctx *context.APIContext) {
result, err := routerRepo.QueryTrainModelFileById(ctx.Context)
if err != nil {
@@ -63,6 +80,21 @@ func QueryTrainModelList(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, re)
}

func QueryTrainJobVersionList(ctx *context.APIContext) {
result, err := routerRepo.QueryTrainJobVersionListApi(ctx.Context)
if err != nil {
log.Info("query error." + err.Error())
ctx.JSON(http.StatusOK, nil)
} else {
re := make([]*api.Cloudbrain, 0)
for _, task := range result {
conRe := convert.ToCloudBrain(task)
re = append(re, conRe)
}
ctx.JSON(http.StatusOK, re)
}
}

func convertFileFormat(result []storage.FileInfo) []FileInfo {
re := make([]FileInfo, 0)
if result != nil {


+ 8
- 6
routers/api/v1/repo/repo_dashbord.go View File

@@ -601,7 +601,7 @@ func getSummaryFileName(ctx *context.Context, beginTime time.Time, endTime time.
func allProjectsPeroidHeader(ctx *context.Context) map[string]string {

return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.openi"), "F1": ctx.Tr("admin.repos.visit"), "G1": ctx.Tr("admin.repos.download"), "H1": ctx.Tr("admin.repos.pr"), "I1": ctx.Tr("admin.repos.commit"),
"J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor"), "P1": ctx.Tr("admin.repos.isFork"), "Q1": ctx.Tr("admin.repos.isMirror"), "R1": ctx.Tr("admin.repos.create")}
"J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor"), "P1": ctx.Tr("admin.repos.numDataset"), "Q1": ctx.Tr("admin.repos.numCloudbrain"), "R1": ctx.Tr("admin.repos.numModel"), "S1": ctx.Tr("admin.repos.numModelConvert"), "T1": ctx.Tr("admin.repos.isFork"), "U1": ctx.Tr("admin.repos.isMirror"), "V1": ctx.Tr("admin.repos.create")}

}

@@ -619,11 +619,13 @@ func allProjectsPeriodSummaryValues(row int, rs *ProjectSummaryBaseData, ctx *co
}

func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string {

return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64),
getCellName("F", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("G", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("H", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("I", row): strconv.FormatInt(rs.NumCommits, 10),
getCellName("J", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("K", row): strconv.FormatInt(rs.NumStars, 10), getCellName("L", row): strconv.FormatInt(rs.NumForks, 10), getCellName("M", row): strconv.FormatInt(rs.NumIssues, 10),
getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("P", row): getBoolDisplay(rs.IsFork, ctx), getCellName("Q", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("R", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT),
getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("P", row): strconv.FormatInt(rs.NumDatasetFile, 10), getCellName("Q", row): strconv.FormatInt(rs.NumCloudbrain, 10), getCellName("R", row): strconv.FormatInt(rs.NumModels, 10), getCellName("S", row): strconv.FormatInt(rs.NumModelConvert, 10), getCellName("T", row): getBoolDisplay(rs.IsFork, ctx), getCellName("U", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("V", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT),
}

}

func allProjectsOpenIHeader() map[string]string {
@@ -804,11 +806,11 @@ func generateOpenICountSql(latestDate string) string {
}

func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string {
sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " +
sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor,num_models,num_model_convert,num_cloudbrain,num_dataset_file FROM " +
"(SELECT repo_id,sum(num_visits) as num_visits " +
" FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
" and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," +
"(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor from public.repo_statistic where date='" + latestDate + "') B" +
"(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor,num_models,num_model_convert,num_cloudbrain,num_dataset_file from public.repo_statistic where date='" + latestDate + "') B" +
" where A.repo_id=B.repo_id"

if q != "" {
@@ -828,8 +830,8 @@ func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string {

func generatePageSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string {

sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " +
"(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor " +
sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor,num_models,num_model_convert,num_cloudbrain,num_dataset_file FROM " +
"(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor,sum(num_models_added) as num_models,sum(num_model_convert_added) as num_model_convert,sum(num_dataset_file_added) as num_dataset_file, sum(num_cloudbrain_added) as num_cloudbrain " +
" FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
" and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," +
"(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total from public.repo_statistic where date='" + latestDate + "') B" +


+ 20
- 0
routers/api/v1/user/repo.go View File

@@ -5,6 +5,7 @@
package user

import (
"code.gitea.io/gitea/modules/modelarts"
"net/http"

"code.gitea.io/gitea/models"
@@ -146,3 +147,22 @@ func ListOrgRepos(ctx *context.APIContext) {

listUserRepos(ctx, ctx.Org.Organization, ctx.IsSigned)
}

func GetComputeNodes(ctx *context.APIContext) {
taskeType := ctx.QueryInt("type")
if taskeType == 2 {
ctx.JSON(http.StatusOK, []int{1})
} else {
modelarts.InitMultiNode()
if modelarts.MultiNodeConfig != nil {
for _, info := range modelarts.MultiNodeConfig.Info {
if isInOrg, _ := models.IsOrganizationMemberByOrgName(info.Org, ctx.User.ID); isInOrg {
ctx.JSON(http.StatusOK, info.Node)
return
}
}
}
ctx.JSON(http.StatusOK, []int{1})
}

}

+ 4
- 0
routers/home.go View File

@@ -42,6 +42,7 @@ const (
tplExploreImages base.TplName = "explore/images"
tplExploreExploreDataAnalysis base.TplName = "explore/data_analysis"
tplHomeTerm base.TplName = "terms"
tplHomeAnnual base.TplName = "annual_privacy"
tplHomePrivacy base.TplName = "privacy"
tplResoruceDesc base.TplName = "resource_desc"
tplRepoSquare base.TplName = "explore/repos/square"
@@ -966,6 +967,9 @@ func RecommendHomeInfo(ctx *context.Context) {
func HomeTerm(ctx *context.Context) {
ctx.HTML(200, tplHomeTerm)
}
func HomeAnnual(ctx *context.Context) {
ctx.HTML(200, tplHomeAnnual)
}

func HomePrivacy(ctx *context.Context) {
ctx.HTML(200, tplHomePrivacy)


+ 21
- 14
routers/repo/ai_model_manage.go View File

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

import (
"archive/zip"
"code.gitea.io/gitea/services/repository"
"encoding/json"
"errors"
"fmt"
@@ -12,6 +11,8 @@ import (
"regexp"
"strings"

"code.gitea.io/gitea/services/repository"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
@@ -75,7 +76,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio
cloudType := aiTask.Type
modelSelectedFile := ctx.Query("modelSelectedFile")
//download model zip //train type
if aiTask.ComputeResource == models.NPUResource {
if aiTask.ComputeResource == models.NPUResource || aiTask.ComputeResource == models.GCUResource {
cloudType = models.TypeCloudBrainTwo
} else if aiTask.ComputeResource == models.GPUResource {
cloudType = models.TypeCloudBrainOne
@@ -710,36 +711,42 @@ func downloadFromCloudBrainTwo(path string, task *models.AiModelManage, ctx *con
}

func QueryTrainJobVersionList(ctx *context.Context) {

VersionListTasks, err := QueryTrainJobVersionListApi(ctx)
if err != nil {
ctx.JSON(200, nil)
} else {
ctx.JSON(200, VersionListTasks)
}
}

func QueryTrainJobVersionListApi(ctx *context.Context) ([]*models.Cloudbrain, error) {
log.Info("query train job version list. start.")
JobID := ctx.Query("jobId")
if JobID == "" {
JobID = ctx.Query("JobId")
}

VersionListTasks, count, err := models.QueryModelTrainJobVersionList(JobID)

log.Info("query return count=" + fmt.Sprint(count))

return VersionListTasks, err
}

func QueryTrainJobList(ctx *context.Context) {
VersionListTasks, err := QueryTrainJobListApi(ctx)
if err != nil {
ctx.ServerError("QueryTrainJobList:", err)
ctx.JSON(200, nil)
} else {
ctx.JSON(200, VersionListTasks)
}
}

func QueryTrainJobList(ctx *context.Context) {
log.Info("query train job list. start.")
func QueryTrainJobListApi(ctx *context.Context) ([]*models.Cloudbrain, error) {
repoId := ctx.QueryInt64("repoId")

VersionListTasks, count, err := models.QueryModelTrainJobList(repoId)
log.Info("query return count=" + fmt.Sprint(count))

if err != nil {
ctx.ServerError("QueryTrainJobList:", err)
} else {
ctx.JSON(200, VersionListTasks)
}

return VersionListTasks, err
}

func QueryTrainModelFileById(ctx *context.Context) ([]storage.FileInfo, error) {


+ 110
- 37
routers/repo/cloudbrain.go View File

@@ -285,7 +285,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
}
var datasetInfos map[string]models.DatasetInfo
var datasetNames string
//var
var attachSize int64
if uuids != "" {
datasetInfos, datasetNames, err = models.GetDatasetInfo(uuids)
if err != nil {
@@ -294,6 +294,18 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}

if jobType == string(models.JobTypeDebug) {
for _, infos := range datasetInfos {
attachSize += infos.Size
}
if attachSize > int64(setting.DebugAttachSize*1000*1000*1000) {
log.Error("The DatasetSize exceeds the limit (%dGB)", setting.DebugAttachSize) // GB
cloudBrainNewDataPrepare(ctx, jobType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.debug_datasetsize", setting.DebugAttachSize), tpl, &form)
return
}
}
}

command := cloudbrain.GetCloudbrainDebugCommand()
@@ -387,7 +399,6 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
req.ModelVersion = form.ModelVersion
req.PreTrainModelPath = setting.Attachment.Minio.RealPath + form.PreTrainModelUrl
req.PreTrainModelUrl = form.PreTrainModelUrl

}

_, err = cloudbrain.GenerateTask(req)
@@ -592,8 +603,10 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra

}

/**
检查用户传输的参数是否符合专属资源池
/*
*

检查用户传输的参数是否符合专属资源池
*/
func checkCloudBrainSpecialPool(ctx *context.Context, jobType string, queue string, resourceSpecId int) string {
if cloudbrain.SpecialPools != nil {
@@ -843,7 +856,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo

if task.JobType == string(models.JobTypeBenchmark) {
task.BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.algorithm")
} else if task.JobType == string(models.JobTypeSnn4imagenet) || task.JobType == string(models.JobTypeBrainScore) {
} else if models.IsModelBenchMarkJobType(task.JobType) {
task.BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.model")
task.BenchmarkTypeName = task.JobType
ctx.Data["BenchmarkTypeName"] = task.JobType
@@ -911,10 +924,13 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo
func CloudBrainDebug(ctx *context.Context) {
task := ctx.Cloudbrain
debugUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName
if task.BootFile != "" {
ctx.Redirect(getFileUrl(debugUrl, task.BootFile))

if ctx.QueryTrim("file") != "" {
ctx.Redirect(getFileUrl(debugUrl, ctx.QueryTrim("file")))
} else {
if task.BootFile != "" {
go cloudbrainTask.UploadNotebookFiles(task)
}
ctx.Redirect(debugUrl)
}

@@ -1306,8 +1322,8 @@ func DeleteJobsByRepoID(repoID int64) {
DeleteJobs(cloudBrains)
}

/**
/*
*
*/
func StopJobs(cloudBrains []*models.Cloudbrain) {

@@ -1638,6 +1654,21 @@ func CloudBrainDownloadModel(ctx *context.Context) {
ctx.Resp.Header().Set("Cache-Control", "max-age=0")
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
}

func CloudBrainDownloadMultiModel(ctx *context.Context) {
parentDir := ctx.Query("parentDir")
jobName := ctx.Query("jobName")
filePath := "jobs/" + jobName + "/model/" + parentDir
allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, filePath)
if err == nil {
returnFileName := jobName + ".zip"
MinioDownloadManyFile(filePath, ctx, returnFileName, allFile)
} else {
log.Info("error,msg=" + err.Error())
ctx.ServerError("no file to download.", err)
}
}

func CloudBrainDownloadInferenceResult(ctx *context.Context) {
parentDir := ctx.Query("parentDir")
fileName := ctx.Query("fileName")
@@ -1674,6 +1705,8 @@ func GetRate(ctx *context.Context) {
ctx.Redirect(setting.Snn4imagenetServerHost)
} else if job.JobType == string(models.JobTypeBrainScore) {
ctx.Redirect(setting.BrainScoreServerHost)
} else if job.JobType == string(models.JobTypeSnn4Ecoset) {
ctx.Redirect(setting.Snn4EcosetServerHost)
} else {
log.Error("JobType error:%s", job.JobType, ctx.Data["msgID"])
}
@@ -2146,7 +2179,7 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) {
}

var jobTypes []string
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeModelSafety))
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeSnn4Ecoset), string(models.JobTypeModelSafety))
ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
ListOptions: models.ListOptions{
Page: page,
@@ -2179,14 +2212,16 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) {
ciTasks[i].BenchmarkTypeName = ""
if ciTasks[i].JobType == string(models.JobTypeBenchmark) {
ciTasks[i].BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.algorithm")
} else if ciTasks[i].JobType == string(models.JobTypeSnn4imagenet) || ciTasks[i].JobType == string(models.JobTypeBrainScore) {
} else if models.IsModelBenchMarkJobType(ciTasks[i].JobType) {
ciTasks[i].BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.model")
ciTasks[i].BenchmarkTypeName = ciTasks[i].JobType

if ciTasks[i].JobType == string(models.JobTypeSnn4imagenet) {
ciTasks[i].BenchmarkTypeRankLink = setting.Snn4imagenetServerHost
} else {
} else if ciTasks[i].JobType == string(models.JobTypeBrainScore) {
ciTasks[i].BenchmarkTypeRankLink = setting.BrainScoreServerHost
} else {
ciTasks[i].BenchmarkTypeRankLink = setting.Snn4EcosetServerHost
}

}
@@ -2536,7 +2571,6 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm)
displayJobName := form.DisplayJobName
jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
image := form.Image
uuid := form.Attachment
jobType := form.JobType
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath
branchName := cloudbrain.DefaultBranchName
@@ -2578,7 +2612,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm)
return
}

if jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) {
if !models.IsModelBenchMarkJobType(jobType) {
log.Error("jobtype error:", jobType, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx, jobType)
ctx.RenderWithErr("jobtype error", tpl, &form)
@@ -2607,29 +2641,41 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm)
mkModelPath(modelPath)
uploadCodeToMinio(modelPath, jobName, cloudbrain.ModelMountPath+"/")

snn4imagenetPath := setting.JobPath + jobName + cloudbrain.Snn4imagenetMountPath
benchmarkPath := setting.JobPath + jobName + cloudbrain.BenchMarkMountPath
if setting.IsSnn4imagenetEnabled && jobType == string(models.JobTypeSnn4imagenet) {
downloadRateCode(repo, jobName, setting.Snn4imagenetOwner, setting.Snn4imagenetName, snn4imagenetPath, "", "", ctx.User.Name)
uploadCodeToMinio(snn4imagenetPath+"/", jobName, cloudbrain.Snn4imagenetMountPath+"/")
command = fmt.Sprintf(cloudbrain.Snn4imagenetCommand, displayJobName, trimSpaceNewlineInString(form.Description))
downloadRateCode(repo, jobName, setting.Snn4imagenetOwner, setting.Snn4imagenetName, benchmarkPath, "", "", ctx.User.Name)
uploadCodeToMinio(benchmarkPath+"/", jobName, cloudbrain.BenchMarkMountPath+"/")
command = fmt.Sprintf(cloudbrain.Snn4imagenetCommand, displayJobName, form.CkptName, trimSpaceNewlineInString(form.Description))

}
benchmarkChildTypeID := 0
brainScorePath := setting.JobPath + jobName + cloudbrain.BrainScoreMountPath
if setting.IsBrainScoreEnabled && jobType == string(models.JobTypeBrainScore) {
downloadRateCode(repo, jobName, setting.BrainScoreOwner, setting.BrainScoreName, brainScorePath, "", "", ctx.User.Name)
uploadCodeToMinio(brainScorePath+"/", jobName, cloudbrain.BrainScoreMountPath+"/")
downloadRateCode(repo, jobName, setting.BrainScoreOwner, setting.BrainScoreName, benchmarkPath, "", "", ctx.User.Name)
uploadCodeToMinio(benchmarkPath+"/", jobName, cloudbrain.BenchMarkMountPath+"/")
benchmarkChildTypeID = form.BenchmarkChildTypeID
command = fmt.Sprintf(cloudbrain.BrainScoreCommand, getBrainRegion(benchmarkChildTypeID), displayJobName, trimSpaceNewlineInString(form.Description))
command = fmt.Sprintf(cloudbrain.BrainScoreCommand, getBrainRegion(benchmarkChildTypeID), displayJobName, form.CkptName, trimSpaceNewlineInString(form.Description))
}
var uuid string
var datasetInfos map[string]models.DatasetInfo
var datasetNames string
if setting.IsSnn4EcosetEnabled && jobType == string(models.JobTypeSnn4Ecoset) {
downloadRateCode(repo, jobName, setting.Snn4EcosetOwner, setting.Snn4EcosetName, benchmarkPath, "", "", ctx.User.Name)
uploadCodeToMinio(benchmarkPath+"/", jobName, cloudbrain.BenchMarkMountPath+"/")
command = fmt.Sprintf(cloudbrain.Snn4EcosetCommand, displayJobName, form.CkptName, trimSpaceNewlineInString(form.Description))

attachment, err := getEcosetAttachment()
if err != nil {
log.Error("load benchmark code failed", err)
cloudBrainNewDataPrepare(ctx, jobType)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form)
return
}
uuid = attachment.UUID
datasetInfos, datasetNames, _ = models.GetDatasetInfo(uuid)

datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
cloudBrainNewDataPrepare(ctx, jobType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}

spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{
JobType: models.JobTypeBenchmark,
ComputeResource: models.GPU,
@@ -2661,8 +2707,6 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm)
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,
Description: form.Description,
BranchName: branchName,
@@ -2674,6 +2718,14 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm)
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"),
Spec: spec,
}
if form.ModelName != "" {
req.ModelName = form.ModelName
req.LabelName = form.LabelName
req.CkptName = form.CkptName
req.ModelVersion = form.ModelVersion
req.PreTrainModelPath = setting.Attachment.Minio.RealPath + form.PreTrainModelUrl
req.PreTrainModelUrl = form.PreTrainModelUrl
}

_, err = cloudbrain.GenerateTask(req)
if err != nil {
@@ -2685,6 +2737,21 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm)
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark")
}

func getEcosetAttachment() (*models.Attachment, error) {
ecosetRepo, err := models.GetRepositoryByOwnerAndName(setting.Snn4EcosetOwner, setting.Snn4EcosetName)
if err != nil {
return nil, err
}

datasetInfo, err := models.GetDatasetByRepo(ecosetRepo)
if err != nil {
return nil, err
}

return models.GetAttachmentByDatasetIdFileName(setting.Snn4AttachmentName, datasetInfo.ID)

}

func getBrainRegion(benchmarkChildTypeID int) string {
values := []string{"V1", "V2", "V4", "IT"}
return values[benchmarkChildTypeID]
@@ -2745,18 +2812,24 @@ func InferenceCloudBrainJobShow(ctx *context.Context) {
cloudBrainShow(ctx, tplCloudBrainInferenceJobShow, models.JobTypeInference)
}

func DownloadInferenceResultFile(ctx *context.Context) {
func DownloadGPUInferenceResultFile(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
var versionName = ctx.Query("version_name")
task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
return
}

allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, task.ResultUrl)
returnFileName := task.DisplayJobName + ".zip"
MinioDownloadManyFile(task.ResultUrl, ctx, returnFileName, allFile)
parentDir := ctx.Query("parentDir")
filePath := "jobs/" + task.JobName + "/result/" + parentDir
log.Info("prefix=" + filePath)
allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, filePath)
if err == nil {
returnFileName := task.DisplayJobName + ".zip"
MinioDownloadManyFile(filePath, ctx, returnFileName, allFile)
} else {
log.Info("error,msg=" + err.Error())
ctx.ServerError("no file to download.", err)
}
}

func getInferenceJobCommand(form auth.CreateCloudBrainInferencForm) (string, error) {


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

@@ -373,6 +373,7 @@ func datasetMultiple(ctx *context.Context, opts *models.SearchDatasetOptions) {
}

data, err := json.Marshal(datasets)
log.Info("datakey", string(data))
if err != nil {
log.Error("json.Marshal failed:", err.Error())
ctx.JSON(200, map[string]string{


+ 78
- 8
routers/repo/grampus.go View File

@@ -53,6 +53,8 @@ const (
//NPU
tplGrampusNotebookNPUNew base.TplName = "repo/grampus/notebook/npu/new"
tplGrampusTrainJobNPUNew base.TplName = "repo/grampus/trainjob/npu/new"
//GCU
tplGrampusNotebookGCUNew base.TplName = "repo/grampus/notebook/gcu/new"
)

func GrampusNotebookNew(ctx *context.Context) {
@@ -61,6 +63,8 @@ func GrampusNotebookNew(ctx *context.Context) {
processType := grampus.ProcessorTypeGPU
if notebookType == 1 {
processType = grampus.ProcessorTypeNPU
} else if notebookType == 2 {
processType = grampus.ProcessorTypeGCU
}
err := grampusNotebookNewDataPrepare(ctx, processType)
if err != nil {
@@ -69,8 +73,10 @@ func GrampusNotebookNew(ctx *context.Context) {
}
if processType == grampus.ProcessorTypeGPU {
ctx.HTML(http.StatusOK, tplGrampusNotebookGPUNew)
} else {
} else if processType == grampus.ProcessorTypeNPU {
ctx.HTML(http.StatusOK, tplGrampusNotebookNPUNew)
} else if processType == grampus.ProcessorTypeGCU {
ctx.HTML(http.StatusOK, tplGrampusNotebookGCUNew)
}

}
@@ -117,6 +123,12 @@ func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebook
computeSource = models.NPUResource
computeSourceSimple = models.NPU
codeStoragePath = grampus.JobPath + jobName + modelarts.CodePath
} else if form.Type == 2 {
tpl = tplGrampusNotebookGCUNew
processType = grampus.ProcessorTypeGCU
computeSource = models.GCUResource
computeSourceSimple = models.GCU
codeStoragePath = setting.CBCodePathPrefix + jobName + cloudbrain.CodeMountPath + "/"
}

lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), string(models.JobTypeDebug), displayJobName))
@@ -190,6 +202,7 @@ func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebook

var datasetInfos map[string]models.DatasetInfo
var datasetNames string
var attachSize int64
//var
if uuid != "" {
datasetInfos, datasetNames, err = models.GetDatasetInfo(uuid, computeSourceSimple)
@@ -199,6 +212,21 @@ func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebook
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}
uuidArray := strings.Split(uuid, ";")
if datasetInfos == nil || len(datasetInfos) < len(uuidArray) {
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.partial_datasets_not_available"), tpl, &form)
return
}
for _, infos := range datasetInfos {
attachSize += infos.Size
}
if attachSize > int64(setting.DebugAttachSize*1000*1000*1000) {
log.Error("The DatasetSize exceeds the limit (%dGB)", setting.DebugAttachSize) // GB
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.debug_datasetsize", setting.DebugAttachSize), tpl, &form)
return
}
}

//prepare code and out path
@@ -215,7 +243,7 @@ func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebook
return
}

if processType == grampus.ProcessorTypeGPU {
if processType == grampus.ProcessorTypeGPU || processType == grampus.ProcessorTypeGCU {
if err := uploadCodeToMinio(codeLocalPath+"/", jobName, cloudbrain.CodeMountPath+"/"); err != nil {
log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
@@ -255,20 +283,26 @@ func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebook

if form.ModelName != "" { //使用预训练模型训练

_, err := models.QueryModelByPath(form.PreTrainModelUrl)
m, err := models.QueryModelByPath(form.PreTrainModelUrl)
if err != nil {
log.Error("Can not find model", err)
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("repo.modelconvert.manage.model_not_exist"), tpl, &form)
return
}
if !cloudbrainTask.IsModelFileExists(m, form.CkptName) {
log.Error("model file not exist.name = %s", form.CkptName)
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("repo.modelconvert.manage.model_file_not_exist"), tpl, &form)
return
}
req.ModelName = form.ModelName
req.LabelName = form.LabelName
req.CkptName = form.CkptName
req.ModelVersion = form.ModelVersion
req.PreTrainModelUrl = form.PreTrainModelUrl
req.PreTrainModelPath = getPreTrainModelPath(form.PreTrainModelUrl, form.CkptName)
req.ModelStorageType = m.Type
}

_, err = grampus.GenerateNotebookJob(ctx, req)
@@ -287,7 +321,7 @@ func grampusNotebookNewDataPrepare(ctx *context.Context, processType string) err
ctx.Data["display_job_name"] = displayJobName

//get valid images
if processType == grampus.ProcessorTypeNPU {
if processType == grampus.ProcessorTypeNPU || processType == grampus.ProcessorTypeGCU {
images, err := grampus.GetImages(processType, string(models.JobTypeDebug))
if err != nil {
log.Error("GetImages failed:", err.Error())
@@ -303,6 +337,10 @@ func grampusNotebookNewDataPrepare(ctx *context.Context, processType string) err
computeResourceSimple = models.NPU
datasetType = models.TypeCloudBrainTwo
computeResource = models.NPUResource
} else if processType == grampus.ProcessorTypeGCU {
computeResourceSimple = models.GCU
datasetType = models.TypeCloudBrainAll
computeResource = models.GCUResource
}

prepareGrampusSpecs(ctx, computeResourceSimple, models.JobTypeDebug)
@@ -1239,7 +1277,7 @@ func GrampusTrainJobShow(ctx *context.Context) {
return
}
task.ContainerIp = ""
task.User, _ = models.GetUserByID(task.UserID)
if task.DeletedAt.IsZero() { //normal record
result, err := grampus.GetJob(task.JobID)
if err != nil {
@@ -1308,6 +1346,7 @@ func GrampusTrainJobShow(ctx *context.Context) {
taskList := make([]*models.Cloudbrain, 0)
taskList = append(taskList, task)
prepareSpec4Show(ctx, task)

ctx.Data["version_list_task"] = taskList
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task)
@@ -1348,16 +1387,39 @@ func GrampusGetLog(ctx *context.Context) {
return
}

result, err := grampus.GetJob(jobID)
if err != nil {
log.Error("GetJob(%s) failed:%v", job.JobName, err)
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobName": job.JobName,
"Content": "",
"CanLogDownload": false,
})
return
}
exitDiagnostics := ""
if result != nil {
exitDiagnostics = result.ExitDiagnostics
}

content, err := grampus.GetTrainJobLog(job.JobID)
if err != nil {
log.Error("GetTrainJobLog failed: %v", err, ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobName": job.JobName,
"Content": "",
"Content": exitDiagnostics,
"CanLogDownload": false,
})
return
}

if result != nil {
job.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
if job.Status == models.GrampusStatusFailed {
content = content + "\n" + exitDiagnostics
}
}

canLogDownload := err == nil && job.IsUserHasRight(ctx.User)
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobName": job.JobName,
@@ -1636,7 +1698,11 @@ func GrampusNotebookRestart(ctx *context.Context) {
if task.ComputeResource == models.NPUResource {
computeSourceSimple = models.NPU
action = models.ActionCreateGrampusNPUDebugTask
} else if task.ComputeResource == models.GCUResource {
computeSourceSimple = models.GCU
action = models.ActionCreateGrampusGCUDebugTask
}

spec, err = resource.GetAndCheckSpec(ctx.User.ID, oldSpec.ID, models.FindSpecsOptions{
JobType: models.JobType(task.JobType),
ComputeResource: computeSourceSimple,
@@ -1652,7 +1718,7 @@ func GrampusNotebookRestart(ctx *context.Context) {
errorMsg = ctx.Tr("points.insufficient_points_balance")
break
}
if task.IsGPUTask() {
if task.IsGPUTask() || task.IsGCUTask() {
if _, err := os.Stat(getOldJobPath(task)); err != nil {
log.Error("Can not find job minio path", err)
resultCode = "-1"
@@ -1682,6 +1748,10 @@ func GrampusNotebookRestart(ctx *context.Context) {
if res.GrampusResult.ErrorCode != 0 || res.NewId == "" {
log.Error("ManageNotebook2 failed:" + res.GrampusResult.ErrorMsg)
errorMsg = ctx.Tr("repo.debug_again_fail")
if res.GrampusResult.ErrorCode == 5005 {
errorMsg = ctx.Tr("repo.debug_again_fail_forever")
}

break
}



+ 78
- 13
routers/repo/modelarts.go View File

@@ -218,6 +218,22 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
return
}
}

var datasetInfos map[string]models.DatasetInfo
var attachSize int64
if uuid != "" {
datasetInfos, _, err = models.GetDatasetInfo(uuid)
for _, infos := range datasetInfos {
attachSize += infos.Size
}
if attachSize > int64(setting.DebugAttachSize*1000*1000*1000) {
log.Error("The DatasetSize exceeds the limit (%dGB)", setting.DebugAttachSize) //GB
notebookNewDataPrepare(ctx)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.debug_datasetsize", setting.DebugAttachSize), tplModelArtsNotebookNew, &form)
return
}
}

var aiCenterCode = models.AICenterOfCloudBrainTwo
if setting.ModelartsCD.Enabled {
aiCenterCode = models.AICenterOfChengdu
@@ -439,9 +455,13 @@ func NotebookDebug2(ctx *context.Context) {
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
return
}
if task.BootFile != "" {
ctx.Redirect(getFileUrl(result.Url, task.BootFile) + "?token=" + result.Token)

if ctx.QueryTrim("file") != "" {
ctx.Redirect(getFileUrl(result.Url, ctx.QueryTrim("file")) + "&token=" + result.Token)
} else {
if task.BootFile != "" {
go cloudbrainTask.UploadNotebookFiles(task)
}
ctx.Redirect(result.Url + "?token=" + result.Token)
}

@@ -463,7 +483,7 @@ func getFileUrl(url string, filename string) string {
}
}

return url + middle + path.Base(filename)
return url + middle + filename + "?reset"
}

func NotebookRestart(ctx *context.Context) {
@@ -630,7 +650,7 @@ func NotebookStop(ctx *context.Context) {
if task.Status != string(models.ModelArtsRunning) {
log.Error("the job(%s) is not running", task.JobName, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "the job is not running"
errorMsg = ctx.Tr("cloudbrain.Already_stopped")
break
}

@@ -2589,7 +2609,8 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
ctx.Data["WaitCount"] = waitCount

NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeInference))
ctx.Data["NotStopTaskCount"] = NotStopTaskCount
return nil
}
func InferenceJobShow(ctx *context.Context) {
@@ -2653,6 +2674,46 @@ func InferenceJobShow(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplModelArtsInferenceJobShow)
}

func MultiModelDownload(ctx *context.Context) {
var (
err error
)
jobID := ctx.Params(":jobid")
versionName := ctx.Query("version_name")
parentDir := ctx.Query("parent_dir")

task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
if err != nil {
log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", task.JobName, err.Error())
return
}

if task.ComputeResource == models.NPUResource {
path := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, task.JobName, setting.OutPutPath, versionName, parentDir), "/")
path = strings.TrimSuffix(path, "/")
path += "/"
allFile, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, path)
if err == nil {
returnFileName := task.DisplayJobName + ".zip"
ObsDownloadManyFile(path, ctx, returnFileName, allFile)
} else {
log.Info("error,msg=" + err.Error())
ctx.ServerError("no file to download.", err)
}
} else if task.ComputeResource == models.GPUResource {
filePath := setting.CBCodePathPrefix + task.JobName + cloudbrain.ModelMountPath + "/" + parentDir
allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, filePath)
if err == nil {
returnFileName := task.DisplayJobName + ".zip"
MinioDownloadManyFile(filePath, ctx, returnFileName, allFile)
} else {
log.Info("error,msg=" + err.Error())
ctx.ServerError("no file to download.", err)
}
}

}

func ModelDownload(ctx *context.Context) {
var (
err error
@@ -2832,15 +2893,19 @@ func TrainJobDownloadLogFile(ctx *context.Context) {
ctx.ServerError("GetObsLogFileName", err)
return
}

url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, key)
if err != nil {
log.Error("GetObsCreateSignedUrlByBucketAndKey failed: %v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("GetObsCreateSignedUrlByBucketAndKey", err)
return
if len(key) > 1 {
ObsDownloadManyFile(prefix[0:len(prefix)-3], ctx, task.DisplayJobName+".zip", key)
} else {
url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, key[0].ParenDir+key[0].FileName)
if err != nil {
log.Error("GetObsCreateSignedUrlByBucketAndKey failed: %v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("GetObsCreateSignedUrlByBucketAndKey", err)
return
}
ctx.Resp.Header().Set("Cache-Control", "max-age=0")
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)
}
ctx.Resp.Header().Set("Cache-Control", "max-age=0")
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)

}
func getDatasUrlListByUUIDS(uuidStr string) ([]models.Datasurl, string, string, bool, error) {
var isMultiDataset bool


+ 9
- 2
routers/repo/repo_statistic.go View File

@@ -75,7 +75,7 @@ func RepoStatisticDaily(date string) {
if repo.NumIssues != 0 {
issueFixedRate = float32(repo.NumClosedIssues) / float32(repo.NumIssues)
} else {
issueFixedRate = 1.0
issueFixedRate = float32(setting.RadarMap.ProjectHealth0IssueCloseRatio)
}

var numVersions int64
@@ -124,7 +124,7 @@ func RepoStatisticDaily(date string) {
NumDevMonths: numDevMonths,
RepoSize: repo.Size,
DatasetSize: datasetSize,
NumModels: 0,
NumModels: repo.ModelCnt,
NumWikiViews: numWikiViews,
NumCommits: numCommits,
NumIssues: int64(repo.NumIssues),
@@ -135,6 +135,9 @@ func RepoStatisticDaily(date string) {
NumCommitsGrowth: numCommitsGrowth,
NumCommitLinesGrowth: numCommitLinesGrowth,
NumContributorsGrowth: numContributorsGrowth,
NumCloudbrain: repo.AiTaskCnt,
NumDatasetFile: repo.DatasetCnt,
NumModelConvert: models.QueryModelConvertCountByRepoID(repo.ID),
}

dayBeforeDate := t.AddDate(0, 0, -1).Format("2006-01-02")
@@ -155,6 +158,10 @@ func RepoStatisticDaily(date string) {
repoStat.NumIssuesAdded = repoStat.NumIssues - repoStatisticBefore.NumIssues
repoStat.NumPullsAdded = repoStat.NumPulls - repoStatisticBefore.NumPulls
repoStat.NumContributorAdded = repoStat.NumContributor - repoStatisticBefore.NumContributor
repoStat.NumModelsAdded = repoStat.NumModels - repoStatisticBefore.NumModels
repoStat.NumCloudbrainAdded = repoStat.NumCloudbrain - repoStatisticBefore.NumCloudbrain
repoStat.NumModelConvertAdded = repoStat.NumModelConvert - repoStatisticBefore.NumModelConvert
repoStat.NumDatasetFileAdded = repoStat.NumDatasetFile - repoStatisticBefore.NumDatasetFile
}
}
day4MonthsAgo := t.AddDate(0, -4, 0)


+ 8
- 3
routers/routes/routes.go View File

@@ -359,6 +359,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/all/dosearch/", routers.SearchApi)
m.Post("/user/login/kanban", user.SignInPostAPI)
m.Get("/home/term", routers.HomeTerm)
m.Get("/home/annual_privacy", routers.HomeAnnual)
m.Get("/home/notice", routers.HomeNoticeTmpl)
m.Get("/home/privacy", routers.HomePrivacy)
m.Get("/extension/tuomin/upload", modelapp.ProcessImageUI)
@@ -1186,6 +1187,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate)
m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels)
m.Get("/download_model", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDownloadModel)
m.Get("/download_multi_model", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDownloadMultiModel)
})
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, context.PointAccount(), repo.CloudBrainNew)
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate)
@@ -1209,6 +1211,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel)
//m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels)
m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel)
m.Get("/download_multi_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadMultiModel)
//m.Get("/get_log", cloudbrain.AdminOrJobCreaterRightForTrain, repo.GetLogFromModelDir)
//m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion)
m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.CloudBrainTrainJobVersionNew)
@@ -1221,8 +1224,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.InferenceCloudBrainJobShow)
m.Get("/result_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.CloudBrainDownloadInferenceResult)
m.Get("/downloadall", repo.DownloadInferenceResultFile)
m.Get("/download_multi_model", cloudbrain.AdminOrJobCreaterRightForTrain, repo.CloudBrainDownloadMultiModel)
m.Get("/downloadall", cloudbrain.AdminOrJobCreaterRightForTrain, repo.DownloadGPUInferenceResultFile)
})
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, context.PointAccount(), repo.InferenceCloudBrainJobNew)
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainInferencForm{}), repo.CloudBrainInferenceJobCreate)
@@ -1248,6 +1251,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.GrampusStopJob)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.GrampusTrainJobDel)
m.Get("/model_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ModelDownload)
m.Get("/download_multi_model", cloudbrain.AdminOrJobCreaterRightForTrain, repo.MultiModelDownload)
m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.GrampusTrainJobVersionNew)
m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateGrampusTrainJobForm{}), repo.GrampusTrainJobVersionCreate)
})
@@ -1333,6 +1337,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.TrainJobStop)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.TrainJobDel)
m.Get("/model_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ModelDownload)
m.Get("/download_multi_model", cloudbrain.AdminOrJobCreaterRightForTrain, repo.MultiModelDownload)
m.Get("/download_log_file", cloudbrain.AdminOrJobCreaterRightForTrain, repo.TrainJobDownloadLogFile)
m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, context.PointAccount(), repo.TrainJobNewVersion)
m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion)
@@ -1348,7 +1353,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.InferenceJobShow)
m.Get("/result_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ResultDownload)
m.Get("/downloadall", repo.DownloadMultiResultFile)
m.Get("/downloadall", cloudbrain.AdminOrJobCreaterRightForTrain, repo.DownloadMultiResultFile)
})
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, context.PointAccount(), repo.InferenceJobNew)
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsInferenceJobForm{}), repo.InferenceJobCreate)


+ 14
- 7
routers/user/auth.go View File

@@ -36,6 +36,7 @@ import (
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/externalaccount"
"code.gitea.io/gitea/services/mailer"
"code.gitea.io/gitea/services/repository"

"gitea.com/macaron/captcha"
"github.com/markbates/goth"
@@ -120,7 +121,6 @@ func checkAutoLogin(ctx *context.Context) bool {
ctx.ServerError("AutoSignIn", err)
return true
}

redirectTo := ctx.Query("redirect_to")
if len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", redirectTo, 0, setting.AppSubURL, "", setting.SessionConfig.Secure, true)
@@ -129,7 +129,6 @@ func checkAutoLogin(ctx *context.Context) bool {
}

if isSucceed {

isCourse := ctx.QueryBool("course")
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL, "", setting.SessionConfig.Secure, true)
if redirectTo == "" && isCourse {
@@ -137,7 +136,6 @@ func checkAutoLogin(ctx *context.Context) bool {
ctx.RedirectToFirst(redirectToCourse)
} else {
ctx.RedirectToFirst(redirectTo, setting.AppSubURL+string(setting.LandingPageURL))

}
return true
}
@@ -145,10 +143,14 @@ func checkAutoLogin(ctx *context.Context) bool {
return false
}

func getActivityTpl() string {
result, _ := repository.RecommendContentFromPromote(setting.RecommentRepoAddr + "/signin/activity_tpl")
return result
}

// SignIn render sign in page
func SignIn(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")

// Check auto-login.
if checkAutoLogin(ctx) {
return
@@ -168,6 +170,7 @@ func SignIn(ctx *context.Context) {
ctx.Data["PageIsLogin"] = true
ctx.Data["EnableSSPI"] = models.IsSSPIEnabled()
ctx.Data["EnableCloudBrain"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignIn)
}
@@ -185,6 +188,7 @@ func SignInCloudBrain(ctx *context.Context) {
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsCloudBrainLogin"] = true
ctx.Data["EnableCloudBrain"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignInCloudBrain)
}
@@ -197,6 +201,7 @@ func SignInPhone(ctx *context.Context) {
}

ctx.Data["PageIsPhoneLogin"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignInPhone)
}
@@ -206,6 +211,7 @@ func SignInPhonePost(ctx *context.Context, form auth.PhoneNumberCodeForm) {
ctx.Data["PageIsPhoneLogin"] = true
ctx.Data["IsCourse"] = ctx.QueryBool("course")
ctx.Data["EnableCloudBrain"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

if ctx.HasError() {
ctx.HTML(200, tplSignInPhone)
@@ -270,7 +276,6 @@ func SignInPostAPI(ctx *context.Context) {

func SignInPostCommon(ctx *context.Context, form auth.SignInForm) {
ctx.Data["Title"] = ctx.Tr("sign_in")

orderedOAuth2Names, oauth2Providers, err := models.GetActiveOAuth2Providers()
if err != nil {
ctx.ServerError("UserSignIn", err)
@@ -285,7 +290,6 @@ func SignInPostCommon(ctx *context.Context, form auth.SignInForm) {
ctx.Data["IsCourse"] = ctx.QueryBool("course")
ctx.Data["EnableSSPI"] = models.IsSSPIEnabled()
ctx.Data["EnableCloudBrain"] = true

if ctx.HasError() {
ctx.HTML(200, tplSignIn)
return
@@ -356,6 +360,7 @@ func SignInPostCommon(ctx *context.Context, form auth.SignInForm) {
func SignInCloudBrainPost(ctx *context.Context, form auth.SignInForm) {
ctx.Data["PageIsCloudBrainLogin"] = true
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login/cloud_brain"
ctx.Data["ActivityTpl"] = getActivityTpl()
SignInPostCommon(ctx, form)
}

@@ -363,6 +368,7 @@ func SignInCloudBrainPost(ctx *context.Context, form auth.SignInForm) {
func SignInPost(ctx *context.Context, form auth.SignInForm) {
ctx.Data["PageIsLogin"] = true
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["ActivityTpl"] = getActivityTpl()
SignInPostCommon(ctx, form)
}

@@ -757,7 +763,6 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
}
return redirectTo
}

if obeyRedirect {
ctx.Redirect(setting.AppSubURL + "/dashboard")
}
@@ -1257,6 +1262,7 @@ func SignUp(ctx *context.Context) {

//Show Disabled Registration message if DisableRegistration or AllowOnlyExternalRegistration options are true
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignUp)
}
@@ -1272,6 +1278,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["PageIsSignUp"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

//Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true
if setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration {


+ 1
- 1
routers/user/home.go View File

@@ -779,7 +779,7 @@ func Cloudbrains(ctx *context.Context) {
var jobTypes []string
jobTypeNot := false
if jobType == string(models.JobTypeBenchmark) {
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet))
jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeSnn4Ecoset))
} else if jobType != "all" && jobType != "" {
jobTypes = append(jobTypes, jobType)
}


+ 14
- 14
services/cloudbrain/clear.go View File

@@ -14,21 +14,21 @@ import (

func ClearCloudbrainResultSpace() {
log.Info("clear cloudbrain one result space begin.")
if !setting.ClearStrategy.Enabled{
if !setting.ClearStrategy.Enabled {
return
}

tasks, err := models.GetCloudBrainOneStoppedNotDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.BatchSize)
tasks, err := models.GetGPUStoppedNotDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.BatchSize)
if err != nil {
log.Warn("Failed to get cloudbrain, clear result failed.", err)
return
}
debugTasks, err := models.GetCloudBrainOneStoppedDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.DebugJobSize)
debugTasks, err := models.GetGPUStoppedDebugJobDaysAgo(setting.ClearStrategy.ResultSaveDays, setting.ClearStrategy.DebugJobSize)
if err != nil {
log.Warn("Failed to get debug cloudbrain.", err)

}
tasks=append(tasks,debugTasks...)
tasks = append(tasks, debugTasks...)

if err != nil {
log.Warn("Failed to get cloudbrain, clear result failed.", err)
@@ -38,7 +38,7 @@ func ClearCloudbrainResultSpace() {
for _, task := range tasks {
err := DeleteCloudbrainOneJobStorage(task.JobName)
if err == nil {
log.Info("clear job in cloudbrain table:"+task.JobName)
log.Info("clear job in cloudbrain table:" + task.JobName)
ids = append(ids, task.ID)
}
}
@@ -69,10 +69,10 @@ func clearMinioHistoryTrashFile() {
SortModTimeAscend(miniofiles)
for _, file := range miniofiles {

if file.Name()!="" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) {
if file.Name() != "" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) {

has,err:=models.IsCloudbrainExistByJobName(file.Name())
if err==nil && !has {
has, err := models.IsCloudbrainExistByJobName(file.Name())
if err == nil && !has {
dirPath := setting.CBCodePathPrefix + file.Name() + "/"
log.Info("clear job in minio trash:" + file.Name())
storage.Attachments.DeleteDir(dirPath)
@@ -90,7 +90,7 @@ func clearMinioHistoryTrashFile() {
}
}

func clearLocalHistoryTrashFile() {
func clearLocalHistoryTrashFile() {
files, err := ioutil.ReadDir(setting.JobPath)
processCount := 0
if err != nil {
@@ -99,11 +99,11 @@ func clearLocalHistoryTrashFile() {
SortModTimeAscend(files)
for _, file := range files {
//清理n天前的历史垃圾数据,清理job目录
if file.Name()!="" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) {
has,err:=models.IsCloudbrainExistByJobName(file.Name())
if err==nil && !has{
if file.Name() != "" && file.ModTime().Before(time.Now().AddDate(0, 0, -setting.ClearStrategy.TrashSaveDays)) {
has, err := models.IsCloudbrainExistByJobName(file.Name())
if err == nil && !has {
os.RemoveAll(setting.JobPath + file.Name())
log.Info("clear job in local trash:"+file.Name())
log.Info("clear job in local trash:" + file.Name())
processCount++
}
if processCount == setting.ClearStrategy.BatchSize {
@@ -127,7 +127,7 @@ func SortModTimeAscend(files []os.FileInfo) {

func DeleteCloudbrainOneJobStorage(jobName string) error {

if jobName==""{
if jobName == "" {
return nil
}
//delete local


+ 30
- 0
services/cloudbrain/cloudbrainTask/ai_model.go View File

@@ -0,0 +1,30 @@
package cloudbrainTask

import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
)

func IsModelFileExists(model *models.AiModelManage, fileName string) bool {
if model.Type == models.TypeCloudBrainTwo {
key := models.AIModelPath + models.AttachmentRelativePath(model.ID) + "/" + fileName
log.Info("IsModelFileExists TypeCloudBrainTwo key=%s", key)
isExist, err := storage.IsObjectExist4Obs(setting.Bucket, key)
if err != nil {
return false
}
return isExist
} else if model.Type == models.TypeCloudBrainOne {
prefix := models.AIModelPath + models.AttachmentRelativePath(model.ID) + "/"
objectName := prefix + fileName
log.Info("IsModelFileExists TypeCloudBrainOne objectName=%s", objectName)
isExist, err := storage.IsObjectExist4Minio(setting.Attachment.Minio.Bucket, objectName)
if err != nil {
return false
}
return isExist
}
return false
}

+ 7
- 2
services/cloudbrain/cloudbrainTask/count.go View File

@@ -34,7 +34,7 @@ var StatusInfoDict = map[string]StatusInfo{string(models.JobTypeDebug) + "-" + s
ComputeResource: models.GPUResource,
}, string(models.JobTypeBenchmark) + "-" + strconv.Itoa(models.TypeCloudBrainOne): {
CloudBrainTypes: []int{models.TypeCloudBrainOne},
JobType: []models.JobType{models.JobTypeBenchmark, models.JobTypeBrainScore, models.JobTypeSnn4imagenet},
JobType: []models.JobType{models.JobTypeBenchmark, models.JobTypeBrainScore, models.JobTypeSnn4imagenet, models.JobTypeSnn4Ecoset},
NotFinalStatuses: CloudbrainOneNotFinalStatuses,
ComputeResource: models.GPUResource,
}, string(models.JobTypeDebug) + "-" + strconv.Itoa(models.TypeCloudBrainTwo): {
@@ -72,11 +72,16 @@ var StatusInfoDict = map[string]StatusInfo{string(models.JobTypeDebug) + "-" + s
JobType: []models.JobType{models.JobTypeDebug},
NotFinalStatuses: GrampusNotFinalStatuses,
ComputeResource: models.NPUResource,
}, string(models.JobTypeDebug) + "-" + strconv.Itoa(models.TypeC2Net) + "-" + models.GCUResource: {
CloudBrainTypes: []int{models.TypeC2Net},
JobType: []models.JobType{models.JobTypeDebug},
NotFinalStatuses: GrampusNotFinalStatuses,
ComputeResource: models.GCUResource,
}}

func GetNotFinalStatusTaskCount(uid int64, cloudbrainType int, jobType string, computeResource ...string) (int, error) {
jobNewType := jobType
if jobType == string(models.JobTypeSnn4imagenet) || jobType == string(models.JobTypeBrainScore) {
if models.IsModelBenchMarkJobType(jobType) {
jobNewType = string(models.JobTypeBenchmark)
}



+ 269
- 29
services/cloudbrain/cloudbrainTask/notebook.go View File

@@ -4,6 +4,9 @@ import (
"fmt"
"net/http"
"path"
"strings"

"code.gitea.io/gitea/modules/notebook"

"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/modelarts_cd"
@@ -29,6 +32,10 @@ import (
)

const NoteBookExtension = ".ipynb"
const CPUType = 0
const GPUType = 1
const NPUType = 2
const CharacterLength = 2550

func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption) {

@@ -40,6 +47,14 @@ func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOp
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_select_wrong")))
return
}
if len(getBootFile(option.File, option.OwnerName, option.ProjectName)) > CharacterLength {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_path_too_long")))
return
}
if len(option.BranchName) > CharacterLength {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_branch_name_too_long")))
return
}

isNotebookFileExist, _ := isNoteBookFileExist(ctx, option)
if !isNotebookFileExist {
@@ -66,7 +81,7 @@ func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOp
}

//create repo if not exist
repo, err := models.GetRepositoryByName(ctx.User.ID, setting.FileNoteBook.ProjectName)
repo, _ := models.GetRepositoryByName(ctx.User.ID, setting.FileNoteBook.ProjectName)
if repo == nil {
repo, err = repo_service.CreateRepository(ctx.User, ctx.User, models.CreateRepoOptions{
Name: setting.FileNoteBook.ProjectName,
@@ -80,19 +95,237 @@ func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOp
AutoInit: true,
DefaultBranch: "master",
})
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.failed_to_create_notebook_repo", setting.FileNoteBook.ProjectName)))
return
}
} else {

noteBook, _ := models.GetWaitOrRunFileNotebookByRepo(repo.ID, getCloudbrainType(option.Type))
if noteBook != nil {

if isRepoConfilcts(option, noteBook) {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_repo_conflict")))
return
}

if isNotebookSpecMath(option, noteBook) {
if !isRepoMatch(option, noteBook) {
err = downloadCode(sourceRepo, getCodePath(noteBook.JobName, sourceRepo), option.BranchName)
if err != nil {
log.Error("download code failed", err)
if !strings.Contains(err.Error(), "already exists and is not an empty directory") {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
return
}
}
}
if !isRepoFileMatch(option, noteBook) {
if len(noteBook.BootFile)+len(getBootFile(option.File, option.OwnerName, option.ProjectName))+1 <= CharacterLength {
noteBook.BootFile += ";" + getBootFile(option.File, option.OwnerName, option.ProjectName)
} else {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_path_too_long")))
return
}
if len(noteBook.BranchName)+len(option.BranchName)+1 <= CharacterLength {
noteBook.BranchName += ";" + option.BranchName
} else {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_branch_name_too_long")))
return
}

if len(noteBook.Description)+len(getDescription(option))+1 <= CharacterLength {
noteBook.Description += ";" + getDescription(option)
}

err := models.UpdateJob(noteBook)
if err != nil {
log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"])
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
return
}
}

ctx.JSON(http.StatusOK, models.BaseMessageApi{
Code: 0,
Message: noteBook.JobID,
})
return
}

}
}

if option.Type <= GPUType {
cloudBrainFileNoteBookCreate(ctx, option, repo, sourceRepo)
} else {
modelartsFileNoteBookCreate(ctx, option, repo, sourceRepo)
}

}
func FileNotebookStatus(ctx *context.Context, option api.CreateFileNotebookJobOption) {
if ctx.Written() {
return
}

if path.Ext(option.File) != NoteBookExtension {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_select_wrong")))
return
}

isNotebookFileExist, _ := isNoteBookFileExist(ctx, option)
if !isNotebookFileExist {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
return
}

task, err := models.GetCloudbrainByJobID(option.JobId)
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.failed_to_create_notebook_repo", setting.FileNoteBook.ProjectName)))
log.Error("job not found:"+option.JobId, err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("Job id may not be right. can not find job."))
return
}
if option.Type <= 1 {
cloudBrainFileNoteBookCreate(ctx, option, repo, sourceRepo)
if task.BootFile == "" || task.Status != string(models.ModelArtsRunning) {
log.Warn("Boot file is empty or status is running. ")
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("Boot file is empty or status is running."))
return
}
if !isRepoFileMatch(option, task) {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("can not math repo file."))
return
}
debugBaseUrl, token, err := getBaseUrlAndToken(task)
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
return
}

if uploadNotebookFileIfCannotBroswer(debugBaseUrl, getBootFile(option.File, option.OwnerName, option.ProjectName), task, token) {
ctx.JSON(http.StatusOK, models.BaseOKMessageApi)
} else {
modelartsFileNoteBookCreate(ctx, option, repo, sourceRepo)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi("upload failed."))

}

}

func getBaseUrlAndToken(task *models.Cloudbrain) (string, string, error) {
var debugBaseUrl string
var token string
if task.Type == models.TypeCloudBrainOne {
debugBaseUrl = setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName + "/lab"

} else {
var result *models.GetNotebook2Result
var err error
if task.Type == models.TypeCloudBrainTwo {
result, err = modelarts.GetNotebook2(task.JobID)
} else if task.Type == models.TypeCDCenter {
result, err = modelarts_cd.GetNotebook(task.JobID)
}
if err != nil || result == nil || result.Status != string(models.ModelArtsRunning) || result.Url == "" {
log.Error("notebook job not found:"+task.JobID, err)
return "", "", fmt.Errorf("can not get job or job is invalid.")
}

debugBaseUrl = result.Url
token = result.Token

}
return debugBaseUrl, token, nil
}

func uploadNotebookFileIfCannotBroswer(debugBaseUrl string, bootFile string, task *models.Cloudbrain, token string) bool {
c := &notebook.NotebookContent{
Url: debugBaseUrl,
Path: bootFile,
PathType: "file",
Token: token,
}
if c.IsNotebookFileCanBrowser() {
return true
} else {
c.SetCookiesAndCsrf()
c.UploadNoteBookFile(task)
return c.IsNotebookFileCanBrowser()
}

}

func isNotebookSpecMath(option api.CreateFileNotebookJobOption, book *models.Cloudbrain) bool {
if option.Type == NPUType || option.Type == CPUType {
return true
}
spec, err := models.GetCloudbrainSpecByID(book.ID)
if err != nil {
log.Warn("can not get spec ", err)
return false
}
return spec.AccCardsNum > 0
}

func isRepoConfilcts(option api.CreateFileNotebookJobOption, book *models.Cloudbrain) bool {
bootFiles := strings.Split(book.BootFile, ";")
branches := strings.Split(book.BranchName, ";")

for i, bootFile := range bootFiles {
splits := strings.Split(bootFile, "/")
if len(splits) >= 3 {
if splits[0] == option.OwnerName && splits[1] == option.ProjectName && branches[i] != option.BranchName {
return true
}
}
}

return false

}

func isRepoMatch(option api.CreateFileNotebookJobOption, book *models.Cloudbrain) bool {
bootFiles := strings.Split(book.BootFile, ";")

for _, bootFile := range bootFiles {
splits := strings.Split(bootFile, "/")
if len(splits) >= 3 {
if splits[0] == option.OwnerName && splits[1] == option.ProjectName {
return true
}
}
}
return false

}

func isRepoFileMatch(option api.CreateFileNotebookJobOption, book *models.Cloudbrain) bool {
bootFiles := strings.Split(book.BootFile, ";")
branches := strings.Split(book.BranchName, ";")

for i, bootFile := range bootFiles {
if branches[i] == option.BranchName && getBootFile(option.File, option.OwnerName, option.ProjectName) == bootFile {
return true
}
}

return false

}
func UploadNotebookFiles(task *models.Cloudbrain) {
if task.Status == string(models.JobRunning) && task.BootFile != "" {

debugBaseUrl, token, err := getBaseUrlAndToken(task)
if err != nil {
log.Error("can not get base url:", err)
return
}
bootFiles := strings.Split(task.BootFile, ";")

for _, bootFile := range bootFiles {
uploadNotebookFileIfCannotBroswer(debugBaseUrl, bootFile, task, token)
}

}
}

func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {

displayJobName := cloudbrainService.GetDisplayJobName(ctx.User.Name)
@@ -131,17 +364,18 @@ func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNot
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
ctx.JSON(http.StatusOK,models.BaseMessageApi{
Code: 2,
ctx.JSON(http.StatusOK, models.BaseMessageApi{
Code: 2,
Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
})
return
}
}

errStr := uploadCodeFile(sourceRepo, getCodePath(jobName), option.BranchName, option.File, jobName)
if errStr != "" {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_file_not_exist")))
err = downloadCode(sourceRepo, getCodePath(jobName, sourceRepo), option.BranchName)
if err != nil {
log.Error("download code failed", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
return
}
command := cloudbrain.GetCloudbrainDebugCommand()
@@ -185,7 +419,7 @@ func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNot
JobType: jobType,
Description: getDescription(option),
BranchName: option.BranchName,
BootFile: option.File,
BootFile: getBootFile(option.File, option.OwnerName, option.ProjectName),
Params: "{\"parameter\":[]}",
CommitID: "",
BenchmarkTypeID: 0,
@@ -206,12 +440,26 @@ func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNot

}

func getCodePath(jobName string) string {
return setting.JobPath + jobName + cloudbrain.CodeMountPath
func getCloudbrainType(optionType int) int {
if optionType <= GPUType {
return models.TypeCloudBrainOne
}
if setting.ModelartsCD.Enabled {
return models.TypeCDCenter
}
return models.TypeCloudBrainTwo
}

func getCodePath(jobName string, repo *models.Repository) string {
return setting.JobPath + jobName + cloudbrain.CodeMountPath + "/" + repo.OwnerName + "/" + repo.Name
}

func getDescription(option api.CreateFileNotebookJobOption) string {
return option.OwnerName + "/" + option.ProjectName + "/" + option.File
des := option.OwnerName + "/" + option.ProjectName + "/" + option.File
if len(des) <= CharacterLength {
return des
}
return ""
}

func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNotebookJobOption, repo *models.Repository, sourceRepo *models.Repository) {
@@ -237,8 +485,8 @@ func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNote
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
ctx.JSON(http.StatusOK,models.BaseMessageApi{
Code: 2,
ctx.JSON(http.StatusOK, models.BaseMessageApi{
Code: 2,
Message: ctx.Tr("repo.cloudbrain.morethanonejob"),
})
return
@@ -260,7 +508,7 @@ func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNote
}
}

err = downloadCode(sourceRepo, getCodePath(jobName), option.BranchName)
err = downloadCode(sourceRepo, getCodePath(jobName, sourceRepo), option.BranchName)
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
return
@@ -297,8 +545,9 @@ func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNote
Description: getDescription(option),
ImageId: setting.FileNoteBook.ImageIdNPU,
Spec: spec,
BootFile: "",
BootFile: getBootFile(option.File, option.OwnerName, option.ProjectName),
AutoStopDurationMs: modelarts.AutoStopDurationMs / 4,
BranchName: option.BranchName,
}

if setting.ModelartsCD.Enabled {
@@ -347,17 +596,8 @@ func isNoteBookFileExist(ctx *context.Context, option api.CreateFileNotebookJobO
return true, nil
}

func uploadCodeFile(repo *models.Repository, codePath string, branchName string, filePath string, jobName string) string {
err := downloadCode(repo, codePath, branchName)
if err != nil {
return "cloudbrain.load_code_failed"
}

err = uploadOneFileToMinio(codePath, filePath, jobName, cloudbrain.CodeMountPath+"/")
if err != nil {
return "cloudbrain.load_code_failed"
}
return ""
func getBootFile(filePath string, ownerName string, projectName string) string {
return ownerName + "/" + projectName + "/" + filePath
}

func fileExists(gitRepo *git.Repository, path string, branch string) (bool, error) {


+ 1
- 1
services/socketwrap/clientManager.go View File

@@ -10,7 +10,7 @@ import (
"github.com/elliotchance/orderedmap"
)

var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 39, 40}
var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 39, 40, 41}

type ClientsManager struct {
Clients *orderedmap.OrderedMap


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

@@ -89,21 +89,21 @@
<div class="row">
<!-- 任务名 -->
{{$JobID := '0'}}
{{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK" "MODELSAFETY"}}
{{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK" "MODELSAFETY" "SNN4ECOSET"}}
{{$JobID = .Cloudbrain.ID}}
{{else}}
{{$JobID = .JobID}}
{{end}}
<!-- {{$JobID}} -->
<div class="two wide column nowrap" style="width:10% !important;">
{{if eq .JobType "DEBUG"}}
{{if eq .JobType "DEBUG"}}
<a class="title"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}"
title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px">
<span class="fitted"
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
</a>
{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}
{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE") (eq .JobType "SNN4ECOSET")}}
<a class="title"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}"
title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px">
@@ -233,7 +233,7 @@
{{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}}
<a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button'
data-jobid="{{$JobID}}"
data-jobid="{{$JobID}}"
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}/'>
{{$.i18n.Tr "repo.debug"}}
</a>
@@ -263,7 +263,7 @@
</a>
</form>
{{else}}
{{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE"}}
{{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE" "SNN4ECOSET"}}
<form id="stopForm-{{$JobID}}" style="margin-left:-1px;">
{{$.CsrfTokenHtml}}
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}"
@@ -305,11 +305,11 @@
</form>
{{else}}
<form class="ui compact buttons" id="delForm-{{$JobID}}"
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true'
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE") (eq .JobType "SNN4ECOSET")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?isadminpage=true'
method="post">
{{$.CsrfTokenHtml}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}"
data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?ishomepage=true"
data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?isadminpage=true"
data-version="{{.VersionName}}" class="ui basic ai_delete blue button"
style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
@@ -321,7 +321,7 @@
</div>
{{else}}
{{$JobID := '0'}}
{{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}}
{{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK" "SNN4ECOSET"}}
{{$JobID = .Cloudbrain.ID}}
{{else}}
{{$JobID = .JobID}}


+ 2
- 0
templates/admin/cloudbrain/search.tmpl View File

@@ -35,6 +35,7 @@
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=SNN4IMAGENET&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="SNN4IMAGENET">SNN4IMAGENET</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BRAINSCORE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="BRAINSCORE">BRAINSCORE</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=MODELSAFETY&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="MODELSAFETY">MODELSAFETY</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=SNN4ECOSET&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="MODELSAFETY">SNN4ECOSET</a>
</div>
</div>
<div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;">
@@ -44,6 +45,7 @@
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value='{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}'>{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=CPU/GPU&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="CPU/GPU">CPU/GPU</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=NPU&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="NPU">NPU</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=GCU&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="GCU">GCU</a>
</div>
</div>
<div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;">


+ 1
- 0
templates/admin/cloudbrain/search_dashboard.tmpl View File

@@ -55,6 +55,7 @@
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value='{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}'>{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=CPU/GPU&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="CPU/GPU">CPU/GPU</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=NPU&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="NPU">NPU</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=GCU&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="GCU">GCU</a>
</div>
</div>
<div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;">


+ 35
- 0
templates/annual_privacy.tmpl View File

@@ -0,0 +1,35 @@
{{template "base/head_home" .}}
<div class="ui container">
<h1 class="ui center am-pt-30 am-pb-20">OpenI启智社区2022年度报告授权协议</h1>
<div class="ui divider am-pb-10"></div>
<p>
感谢您阅读《OpenI启智社区2022年度报告授权协议》!在您正式使用OpenI启智社区2022年度报告之前应仔细阅读并充分理解本协议中的全部内容,如您不同意本协议中的任何条款,请立即停止使用OpenI启智社区2022年度报告。您使用OpenI启智社区2022年度报告的行为将被视为已经仔细阅读、充分理解并毫无保留地接受本协议所有条款。
</p>
<p>
<strong>1. 制作年度报告</strong>
</p>
<p>
OpenI启智社区2022年度报告将根据您在平台的历史信息,帮助您生成一份专属年度报告。为此,我们将使用2022自然年度您在OpenI启智社区产生的行为信息,包括但不限于用户名、注册时间、创建项目数、项目下载次数、commit次数、代码行数、创建数据集、上传数据集文件、数据集被收藏数、数据集下载数、云脑任务所有相关数据( GPU/NPU 调试任务、训练任务、运行卡时)。您理解并同意,上述信息是OpenI启智社区生成年度报告的必备信息,如您拒绝授权使用,OpenI启智社区将无法为您制作并提供专属年度报告。未经您的书面同意,我们保证不以超越本协议约定范围使用您的个人信息。
</p>
<p>
<strong>2. 使用年度报告</strong>
</p>
<p>
OpenI启智社区提供的年度报告仅限您个人使用,您可自行留存欣赏或无偿分享、公开。您理解并同意,如因您分享、公开年度报告而产生的任何损失(包括但不限于个人信息泄露等)应由您自行承担,请您在分享、公开年度报告前审慎考虑。
</p>
<p>
<strong>3. 知识产权</strong>
</p>
<p>
年度报告及其内容(包括但不限于软件、技术、程序、网页、文字、图片、音频、视频、页面设计、商标等)的知识产权由OpenI启智社区享有,您理解并同意,您不得超越本协议目的使用年度报告中的内容素材,如您希望以任何形式将年度报告中的内容素材用于本协议约定范围之外,应当经过所有实际权利人的书面许可。
</p>
<p>
<strong>4. 隐私政策</strong>
</p>
<p>
其他本隐私保护指引未有涉及的,将适用<a target="_blank" href="/home/term/">《OpenI启智社区AI协作平台使用协议》</a>和<a target="_blank" href="/home/privacy/">《OpenI启智社区AI协作平台隐私协议》</a>。
</p>

</div>
{{template "base/footer" .}}

+ 9
- 9
templates/base/footer.tmpl View File

@@ -17,9 +17,9 @@

{{if .RequireSimpleMDE}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js?v={{MD5 AppVer}}"></script>
<script>
CodeMirror.modeURL = "{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/%N/%N.js";
</script>
@@ -27,10 +27,10 @@

<!-- Third-party libraries -->
{{if .RequireMinicolors}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js?v={{MD5 AppVer}}"></script>
{{end}}
{{if .RequireU2F}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/u2f/index.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/u2f/index.js?v={{MD5 AppVer}}"></script>
{{end}}
{{if .EnableCaptcha}}
{{if eq .CaptchaType "recaptcha"}}
@@ -38,17 +38,17 @@
{{end}}
{{end}}
{{if .RequireTribute}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.min.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.min.js?v={{MD5 AppVer}}"></script>
{{end}}
{{if .PageIsHome}}
<script rel="stylesheet" src="{{StaticUrlPrefix}}/vendor/plugins/jquery.particleground/jquery.particleground.min.js"></script>
<script rel="stylesheet" src="{{StaticUrlPrefix}}/vendor/plugins/jquery.particleground/jquery.particleground.min.js?v={{MD5 AppVer}}"></script>
{{end}}
<script src="{{StaticUrlPrefix}}/fomantic/semantic.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script>
{{template "custom/footer" .}}
{{if .PageIsHome}}
<!--script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script-->
<script src="/rotation3D/vue-2.6.10.min.js"></script>
<!--script src="https://www.jq22.com/jquery/jquery-1.10.2.js?v={{MD5 AppVer}}"></script-->
<script src="/rotation3D/vue-2.6.10.min.js?v={{MD5 AppVer}}"></script>
<script src="/rotation3D/rotation3D.js?v={{MD5 AppVer}}"></script>
<script>
var jobTask={};


+ 10
- 0
templates/base/footer_content.tmpl View File

@@ -1,3 +1,13 @@
<style>
@media only screen and (max-width: 767px) {
.mobile-text-align-center {
text-align: center !important;
}
.mobile-justify-content-center {
justify-content: center !important;
}
}
</style>
<footer style="border-top:none;">
<div class="ui container">
<div class="ui grid">


+ 7
- 7
templates/base/footer_fluid.tmpl View File

@@ -14,9 +14,9 @@
<script src="{{StaticUrlPrefix}}/js/jquery.js?v={{MD5 AppVer}}"></script>
{{if .RequireSimpleMDE}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/addon/mode/loadmode.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/meta.js?v={{MD5 AppVer}}"></script>
<script>
CodeMirror.modeURL = "{{StaticUrlPrefix}}/vendor/plugins/codemirror/mode/%N/%N.js";
</script>
@@ -24,10 +24,10 @@
<!-- Third-party libraries -->
{{if .RequireMinicolors}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.min.js?v={{MD5 AppVer}}"></script>
{{end}}
{{if .RequireU2F}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/u2f/index.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/u2f/index.js?v={{MD5 AppVer}}"></script>
{{end}}
{{if .EnableCaptcha}}
{{if eq .CaptchaType "recaptcha"}}
@@ -35,10 +35,10 @@
{{end}}
{{end}}
{{if .RequireTribute}}
<script src="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.min.js"></script>
<script src="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.min.js?v={{MD5 AppVer}}"></script>
{{end}}
{{if .PageIsHome}}
<script rel="stylesheet" src="{{StaticUrlPrefix}}/vendor/plugins/jquery.particleground/jquery.particleground.min.js"></script>
<script rel="stylesheet" src="{{StaticUrlPrefix}}/vendor/plugins/jquery.particleground/jquery.particleground.min.js?v={{MD5 AppVer}}"></script>
{{end}}
<script src="{{StaticUrlPrefix}}/fomantic/semantic.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script>


+ 10
- 10
templates/base/head.tmpl View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{{if .Title}}{{.Title}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
<link rel="manifest" href="{{AppSubUrl}}/manifest.json?v={{MD5 AppVer}}" crossorigin="use-credentials">
{{if UseServiceWorker}}
<script>
if ('serviceWorker' in navigator) {
@@ -115,18 +115,18 @@
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css">
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png?v={{MD5 AppVer}}">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg?v={{MD5 AppVer}}" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png?v={{MD5 AppVer}}" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css?v={{MD5 AppVer}}">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/icons.woff2" type="font/woff2" crossorigin="anonymous">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/outline-icons.woff2" type="font/woff2" crossorigin="anonymous">
{{if .RequireSimpleMDE}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css?v={{MD5 AppVer}}">
{{end}}

{{if .RequireTribute}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/fomantic/semantic.min.css?v={{MD5 AppVer}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}">
@@ -137,7 +137,7 @@
</style>
</noscript>
{{if .RequireMinicolors}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css?v={{MD5 AppVer}}">
{{end}}
<style class="list-search-style"></style>
{{if .PageIsUserProfile}}
@@ -179,7 +179,7 @@
{{else if ne DefaultTheme "gitea"}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/theme-{{DefaultTheme}}.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css">
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css?v={{MD5 AppVer}}">
{{template "custom/header" .}}

<script>
@@ -191,7 +191,7 @@ var _hmt = _hmt || [];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script src="/self/func.js" type="text/javascript"></script>
<script src="/self/func.js?v={{MD5 AppVer}}" type="text/javascript"></script>
</head>
<body>
{{template "custom/body_outer_pre" .}}


+ 10
- 10
templates/base/head_course.tmpl View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{{if .Title}}{{.Title}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
<link rel="manifest" href="{{AppSubUrl}}/manifest.json?v={{MD5 AppVer}}" crossorigin="use-credentials">
{{if UseServiceWorker}}
<script>
if ('serviceWorker' in navigator) {
@@ -115,18 +115,18 @@
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css">
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png?v={{MD5 AppVer}}">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg?v={{MD5 AppVer}}" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png?v={{MD5 AppVer}}" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css?v={{MD5 AppVer}}">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/icons.woff2" type="font/woff2" crossorigin="anonymous">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/outline-icons.woff2" type="font/woff2" crossorigin="anonymous">
{{if .RequireSimpleMDE}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css?v={{MD5 AppVer}}">
{{end}}

{{if .RequireTribute}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/fomantic/semantic.min.css?v={{MD5 AppVer}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}">
@@ -137,7 +137,7 @@
</style>
</noscript>
{{if .RequireMinicolors}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css?v={{MD5 AppVer}}">
{{end}}
<style class="list-search-style"></style>
{{if .PageIsUserProfile}}
@@ -179,7 +179,7 @@
{{else if ne DefaultTheme "gitea"}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/theme-{{DefaultTheme}}.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css">
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css?v={{MD5 AppVer}}">
{{template "custom/header" .}}

<script>
@@ -191,7 +191,7 @@ var _hmt = _hmt || [];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script src="/self/func.js" type="text/javascript"></script>
<script src="/self/func.js?v={{MD5 AppVer}}" type="text/javascript"></script>
</head>
<body>
{{template "custom/body_outer_pre" .}}


+ 10
- 10
templates/base/head_fluid.tmpl View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{{if .Title}}{{.Title}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
<link rel="manifest" href="{{AppSubUrl}}/manifest.json?v={{MD5 AppVer}}" crossorigin="use-credentials">
{{if UseServiceWorker}}
<script>
if ('serviceWorker' in navigator) {
@@ -115,18 +115,18 @@
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css">
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png?v={{MD5 AppVer}}">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg?v={{MD5 AppVer}}" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png?v={{MD5 AppVer}}" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css?v={{MD5 AppVer}}">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/icons.woff2" type="font/woff2" crossorigin="anonymous">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/outline-icons.woff2" type="font/woff2" crossorigin="anonymous">
{{if .RequireSimpleMDE}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css?v={{MD5 AppVer}}">
{{end}}

{{if .RequireTribute}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/fomantic/semantic.min.css?v={{MD5 AppVer}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}">
@@ -137,7 +137,7 @@
</style>
</noscript>
{{if .RequireMinicolors}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css?v={{MD5 AppVer}}">
{{end}}
<style class="list-search-style"></style>
{{if .PageIsUserProfile}}
@@ -179,7 +179,7 @@
{{else if ne DefaultTheme "gitea"}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/theme-{{DefaultTheme}}.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css">
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css?v={{MD5 AppVer}}">
{{template "custom/header" .}}

<script>
@@ -191,7 +191,7 @@ var _hmt = _hmt || [];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script src="/self/func.js" type="text/javascript"></script>
<script src="/self/func.js?v={{MD5 AppVer}}" type="text/javascript"></script>

</head>
<body>


+ 14
- 14
templates/base/head_home.tmpl View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{{if .Title}}{{.Title}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
<link rel="manifest" href="{{AppSubUrl}}/manifest.json?v={{MD5 AppVer}}" crossorigin="use-credentials">
{{if UseServiceWorker}}
<script>
if ('serviceWorker' in navigator) {
@@ -115,19 +115,19 @@
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css">
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png?v={{MD5 AppVer}}">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg?v={{MD5 AppVer}}" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png?v={{MD5 AppVer}}" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css?v={{MD5 AppVer}}">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/icons.woff2" type="font/woff2" crossorigin="anonymous">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/outline-icons.woff2" type="font/woff2" crossorigin="anonymous">
<link rel="stylesheet" href="/css/git.openi.css">
<link rel="stylesheet" href="/css/git.openi.css?v={{MD5 AppVer}}">
{{if .RequireSimpleMDE}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css?v={{MD5 AppVer}}">
{{end}}

{{if .RequireTribute}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/fomantic/semantic.min.css?v={{MD5 AppVer}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}">
@@ -138,7 +138,7 @@
</style>
</noscript>
{{if .RequireMinicolors}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css?v={{MD5 AppVer}}">
{{end}}
<style class="list-search-style"></style>
{{if .PageIsUserProfile}}
@@ -191,14 +191,14 @@ var _hmt = _hmt || [];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script src="/self/func.js" type="text/javascript"></script>
<script src="/self/func.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<!--RemixIcon Fonts v2.5.0-->
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css">
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css?v={{MD5 AppVer}}">
<!-- Swiper -->
<link rel="stylesheet" href="/swiper/swiper-bundle.min.css">
<script src="/swiper/swiper-bundle.min.js"></script>
<link rel="stylesheet" href="/swiper/swiper-bundle.min.css?v={{MD5 AppVer}}">
<script src="/swiper/swiper-bundle.min.js?v={{MD5 AppVer}}"></script>
<!-- rotation3D -->
<link rel="stylesheet" href="/rotation3D/rotation3D.css">
<link rel="stylesheet" href="/rotation3D/rotation3D.css?v={{MD5 AppVer}}">
</head>
<body>
{{template "custom/body_outer_pre" .}}


+ 10
- 10
templates/base/head_pro.tmpl View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{{if .Title}}{{.Title}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}}</title>
<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
<link rel="manifest" href="{{AppSubUrl}}/manifest.json?v={{MD5 AppVer}}" crossorigin="use-credentials">
{{if UseServiceWorker}}
<script>
if ('serviceWorker' in navigator) {
@@ -115,18 +115,18 @@
window.sessionStorage.removeItem('_csrf');
{{end}}
</script>
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css">
<link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png?v={{MD5 AppVer}}">
<link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg?v={{MD5 AppVer}}" color="#609926">
<link rel="fluid-icon" href="{{StaticUrlPrefix}}/img/gitea-lg.png?v={{MD5 AppVer}}" title="{{AppName}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/assets/font-awesome/css/font-awesome.min.css?v={{MD5 AppVer}}">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/icons.woff2" type="font/woff2" crossorigin="anonymous">
<link rel="preload" as="font" href="{{StaticUrlPrefix}}/fomantic/themes/default/assets/fonts/outline-icons.woff2" type="font/woff2" crossorigin="anonymous">
{{if .RequireSimpleMDE}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/simplemde/simplemde.min.css?v={{MD5 AppVer}}">
{{end}}

{{if .RequireTribute}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/tribute/tribute.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/fomantic/semantic.min.css?v={{MD5 AppVer}}">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/index.css?v={{MD5 AppVer}}">
@@ -137,7 +137,7 @@
</style>
</noscript>
{{if .RequireMinicolors}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
<link rel="stylesheet" href="{{StaticUrlPrefix}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css?v={{MD5 AppVer}}">
{{end}}
<style class="list-search-style"></style>
{{if .PageIsUserProfile}}
@@ -179,7 +179,7 @@
{{else if ne DefaultTheme "gitea"}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/theme-{{DefaultTheme}}.css?v={{MD5 AppVer}}">
{{end}}
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css">
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css?v={{MD5 AppVer}}">
{{template "custom/header" .}}

<script>
@@ -191,7 +191,7 @@ var _hmt = _hmt || [];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script src="/self/func.js" type="text/javascript"></script>
<script src="/self/func.js?v={{MD5 AppVer}}" type="text/javascript"></script>

</head>
<body>


+ 2
- 0
templates/custom/header.tmpl View File

@@ -0,0 +1,2 @@
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/placeholder.css?v={{TimeStampNow}}">
<script src="{{StaticUrlPrefix}}/js/placeholder.js?v={{TimeStampNow}}"></script>

+ 39
- 1
templates/custom/home/home_top.tmpl View File

@@ -1786,8 +1786,40 @@
background-repeat: no-repeat;
background-size: cover;
padding: 45% 0;
}
}
}

._hm-pg-bg-4 {
background: url(/img/home-banner-02-1.jpg);
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
._hm-pg-bg-4-content {
position: absolute;
margin: auto;
left: 0;
top: -10%;
right: 0;
bottom: 0;
display: block;
width: 790px;
height: 315px;
background: url(/img/home-banner-02-2.png);
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
@media only screen and (max-width: 767px) {
._hm-pg-bg-4 {
background-size: 200% 100%;
}
._hm-pg-bg-4-content {
top: -15%;
width: 90%;
height: 150px;
}
}
</style>
<div class="_hm-bg-container">
<div class="_hm-pg _hm-pg-static">
@@ -2029,12 +2061,18 @@
<div class="_hm-big-btn-c"></div>
</div>
</div>
<div class="_hm-pg _hm-pg-bg-4">
<a target="_blank;" href="https://openi.org.cn/index.php?m=content&c=index&a=lists&catid=225">
<div class="_hm-pg-bg-4-content" style="animation:_hm-slide-in-left-once 0.5s"></div>
</a>
</div>
</div>
<div class="_hm-slide-btn _hm-slide-btn-left"></div>
<div class="_hm-slide-btn _hm-slide-btn-right"></div>
<div class="_hm-slide-pagination-c">
<div class="_hm-slide-pagination-item _hm-slide-pagination-item-active"></div>
<div class="_hm-slide-pagination-item"></div>
<div class="_hm-slide-pagination-item"></div>
</div>
</div>
<div class="ui container _hm-container">


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

@@ -1,7 +1,7 @@
<div style="display:inline-block;">
<div style="display:flex;align-items:center;color:#f2711c;">
<i class="ri-error-warning-line" style="margin-right: 0.5rem; font-size: 14px"></i>
<span style="font-size: 12px">{{.i18n.Tr "repo.wait_count_start"}} <span class="__task_wait_count__">{{.WaitCount}}</span> {{.i18n.Tr "repo.wait_count_end"}}</span>
<span style="font-size: 12px">{{.i18n.Tr "repo.wait_count_start"}} <span class="__task_wait_count__">{{if not .WaitCount}}1{{else}}{{addOne .WaitCount}}{{end}}</span> {{.i18n.Tr "repo.wait_count_end"}}</span>
</div>
</div>
<script>
@@ -12,7 +12,7 @@
var specsSelEl = $('select#__specs__');
var seldOption = specsSelEl.find('option:selected');
var queueCode = seldOption.attr('queueCode');
$('span.__task_wait_count__').text(queuesDetail[queueCode] || 0);
$('span.__task_wait_count__').text((queuesDetail[queueCode] || 0) +1);
};
$('body').on('change', 'select#__specs__', function(e) {
changeSpecs();


+ 1
- 0
templates/explore/images.tmpl View File

@@ -1,4 +1,5 @@
{{template "base/head" .}}
<div class="alert"></div>
<div id="images"></div>
<!-- 确认模态框 -->
<div id="deletemodel">


+ 4
- 4
templates/explore/organizations.tmpl View File

@@ -1,8 +1,8 @@

<link rel="stylesheet" href="/swiper/swiper-bundle.min.css">
<link rel="stylesheet" href="/css/git.openi.css">
<script src="/swiper/swiper-bundle.min.js"></script>
<script src="/self/js/jquery.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="/swiper/swiper-bundle.min.css?v={{MD5 AppVer}}">
<link rel="stylesheet" href="/css/git.openi.css?v={{MD5 AppVer}}">
<script src="/swiper/swiper-bundle.min.js?v={{MD5 AppVer}}"></script>
<script src="/self/js/jquery.min.js?v={{MD5 AppVer}}" type="text/javascript"></script>

{{template "base/head" .}}
<div class="explore users">


+ 2
- 2
templates/explore/repo_orgtop.tmpl View File

@@ -1,5 +1,5 @@
<script src="/swiper/swiper-bundle.min.js"></script>
<link href="/swiper/swiper-bundle.min.css" rel="stylesheet">
<script src="/swiper/swiper-bundle.min.js?v={{MD5 AppVer}}"></script>
<link href="/swiper/swiper-bundle.min.css?v={{MD5 AppVer}}" rel="stylesheet">

<style>
.explore .repos--seach{


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

@@ -86,7 +86,7 @@
</div>

</div>
<script src="/self/js/jquery.min.js" type="text/javascript"></script>
<script src="/self/js/jquery.min.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script src="/home/search.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<div class="am-mt-30"></div>



+ 3
- 1
templates/home.tmpl View File

@@ -1,4 +1,6 @@
{{template "base/head_home" .}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/placeholder-home.css?v={{TimeStampNow}}">
<script src="{{StaticUrlPrefix}}/js/placeholder-home.js?v={{TimeStampNow}}"></script>
<div class="ui vertical masthead secondary hometop segment" style="background:transparent;margin-bottom:0">
{{template "custom/home/home_top" .}}
</div>
@@ -160,7 +162,7 @@
-->

<!-- <div class="am-mt-30"></div> -->
<script src="/self/js/jquery.min.js" type="text/javascript"></script>
<script src="/self/js/jquery.min.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script src="/home/home.js?v={{MD5 AppVer}}" type="text/javascript"></script>




+ 125
- 259
templates/repo/cloudbrain/benchmark/new.tmpl View File

@@ -1,37 +1,9 @@
{{template "base/head" .}}
<style>
.unite {
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;
margin-bottom: 2rem !important;
}

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

.width48 {
width: 48.5% !important;
}

.nowrapx {
white-space: nowrap !important;
}
</style>
{{template "custom/global_mask" .}}
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-repo-link="{{.RepoLink}}" data-flag-model="true"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
@@ -54,7 +26,7 @@
<a class="active item model_benchmark"
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a>
<a class="item aisafety_benchmark"
href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a>
href="{{.RepoLink}}/modelsafety/create_gpu">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>
<div>
@@ -78,21 +50,12 @@
onkeydown="this.value=this.value.substring(0, 255)"
onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea>
</div>

<!--<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<select id="cloudbrain_gpu_type" class="ui search dropdown width48" placeholder="选择GPU类型"
name="gpu_type">
{{range .benchmark_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
</select>
</div>-->
<div class="required unite min_title two inline fields" style="margin-left: 80px;">
<div class="required min_title two inline fields" style="margin-left: 80px;">
<div class="required ten wide field" style="width: 26.5% !important;">
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label>&nbsp;
<select id="cloudbrain_job_type" class="ui search dropdown job_type"
<select id="cloudbrain_job_type" class="ui search dropdown job_type"
placeholder="select {{.i18n.Tr "cloudbrain.task_type"}}" name="job_type">
<option value="SNN4ECOSET">SNN4ECOSET</option>
<option value="SNN4IMAGENET">SNN4IMAGENET</option>
<option value="BRAINSCORE">BRAINSCORE</option>
</select>
@@ -116,22 +79,10 @@
<a id="benchmark_model_example" href="https://openi.pcl.ac.cn/BDIP/snn4imagenet"
target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>
{{template "custom/select_model" .}}
<div id="images-new-cb">
</div>
{{template "custom/select_dataset_train" .}}
<!--<div class="required min_title inline field" style="margin-top:2rem;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="cloudbrain_resource_spec" class="ui search dropdown"
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px'
name="resource_spec_id">
{{range .benchmark_resource_specs}}
<option name="resource_spec_id" value="{{.Id}}">
{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}
</option>
{{end}}
</select>
</div>-->
<div class="required min_title inline field" style="margin-top:2rem;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="__specs__" class="ui search dropdown width48"
@@ -156,7 +107,7 @@
<button class="ui create_train_job green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
<a class="ui button" href="{{.RepoLink}}/cloudbrain/benchmark">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
</div>
</form>
@@ -173,7 +124,7 @@
<a class="item model_benchmark"
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a>
<a class="item aisafety_benchmark"
href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a>
href="{{.RepoLink}}/modelsafety/create_gpu">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>

@@ -199,20 +150,11 @@
onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea>
</div>

<!--<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型"
style='width:385px' name="gpu_type">
{{range .benchmark_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
</select>
</div>-->
<div class="required unite inline min_title fields" style="width: 90%;margin-left: 5.7rem;">&nbsp;
<div class="required inline min_title fields" style="width: 90%;margin-left: 5.7rem;">&nbsp;
<div class="required eight wide field">
<label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label>

<select class="ui fluid selection search dropdown" id="benchmark_types_id"
<select class="ui fluid selection search dropdown benchmark_types_id"
name="benchmark_types_id">
{{range .benchmark_types}}
{{if eq .Id $.benchmarkTypeID}}
@@ -226,26 +168,13 @@
<div class="eight wide field" id="engine_name">
<input type="hidden" id="benchmark_child_types_id_hidden" name="benchmark_child_types_id_hidden" value="{{.benchmark_child_types_id_hidden}}">
<label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_child_type"}}</label>
<select class="ui fluid selection dropdown nowrapx" id="benchmark_child_types_id" style='width: 100%;' name="benchmark_child_types_id">
<select class="ui fluid selection dropdown " id="benchmark_child_types_id" style='width: 100%;' name="benchmark_child_types_id">
</select>
</div>
</div>
<div id="images-new-cb">
</div>

<!--<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="cloudbrain_resource_spec" class="ui search dropdown"
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px'
name="resource_spec_id">
{{range .benchmark_resource_specs}}
<option name="resource_spec_id" value="{{.Id}}">
{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}
</option>
{{end}}
</select>
</div>-->

<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="__specs__" class="ui search dropdown width48"
@@ -282,197 +211,134 @@
target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>


<div class="inline unite min_title field">
<label class="label-fix-width" style="font-weight: normal;"></label>
<button class="ui create_train_job green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
</div>
</form>
{{else if eq .benchmarkMode "aisafety"}}
<form id="form_id" class="ui form alogrithm_form" action="{{.Link}}?benchmarkMode=alogrithm" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<input type="hidden" name="job_type" value="BENCHMARK">
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="item alogrithm_benchmark"
href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a>
<a class="item model_benchmark"
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a>
<a class="active item aisafety_benchmark"
href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a>
</div>
</div>

<div>
<div class="min_title inline field" style="margin-top:-10px;">
<label class="label-fix-width" style="font-weight: normal;"></label>
{{template "custom/task_wait_count" .}}
</div>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 80%;" name="display_job_name" id="trainjob_job_name"
placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}"
tabindex="3" autofocus required maxlength="36">
<span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span>
</div>
<div class="min_title inline field">
<label class="label-fix-width" style="font-weight: normal;"
for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="254"
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)">{{.description}}</textarea>
</div>


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

<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="__specs__" class="ui search dropdown width48"
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}"
name="spec_id">
</select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
</div>

<div class="inline min_title field required">
<label class="label-fix-width" style="font-weight: normal;">推理程序</label>
<input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py"
tabindex="3" autofocus required maxlength="254">
<a id="test_href_id" href="https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark"
target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>


<div class="inline unite min_title field">
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;"></label>
<button class="ui create_train_job green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
<a class="ui button" href="{{.RepoLink}}/cloudbrain/benchmark">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
</div>
</form>

{{end}}
</div>
</div>
</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
let form = document.getElementById('form_id');
let createFlag = false
form.onsubmit = function (e) {
if(createFlag) return false
createFlag = true
}
let repolink = {{.RepoLink }}
let url_href = window.location.pathname.split('create')[0]
$(".ui.button").attr('href', url_href)
$('.menu .item')
.tab();
$('#benchmark_types_id').change(function () {
setChildType();
})
$(document).ready(() => {
$('.ui.search.dropdown.job_type').dropdown({
onChange: function (value, text, $selectedItem) {
if (value === "BRAINSCORE") {
$('#brainscore_child_type').css('display', 'block')
$('#benchmark_model_example').attr('href', 'https://openi.pcl.ac.cn/BDIP/similarity2brain_ann')
} else {
$('#brainscore_child_type').css('display', 'none')
$('#benchmark_model_example').attr('href', 'https://openi.pcl.ac.cn/BDIP/snn4imagenet')
}
}
})
})
function setChildType() {
let type_id = $('#benchmark_types_id').val();
if (type_id == 3) {
$('#train_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_MOT_benchmark');
$('#test_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_MOT_benchmark');
} else {
$('#train_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark');
$('#test_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark');
}
let child_selected_id = $('#benchmark_child_types_id_hidden').val();
$.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => {
const n_length = data['child_types'].length
let html = ''
for (let i = 0; i < n_length; i++) {
if (child_selected_id == data['child_types'][i].id) {
html += `<option value="${data['child_types'][i].id}" selected="true">${data['child_types'][i].value}</option>`;
} else {
html += `<option value="${data['child_types'][i].id}">${data['child_types'][i].value}</option>`;
}
}
document.getElementById("benchmark_child_types_id").innerHTML = html;
})
}
document.onreadystatechange = function () {
if (document.readyState === "complete") {
if ($('input[name=benchmarkMode]').val() === 'alogrithm' || $('input[name=benchmarkMode]').val() === '') {
setChildType();
}
}
}
var isValidate = false;
function validate() {
$('.ui.form')
.form({
on: 'blur',
fields: {
image: {
identifier: 'image',
rules: [
{
type: 'empty',
promt: ''
}
]
},
display_job_name: {
identifier: 'display_job_name',
rules: [
{
type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]',
promt: ''
}
]
},
spec_id: {
identifier: 'spec_id',
rules: [{ type: 'empty' }]
}
},
onSuccess: function () {
// $('.ui.page.dimmer').dimmer('show')
document.getElementById("mask").style.display = "block"
isValidate = true;
},
onFailure: function (e) {
isValidate = false;
return false;
}
})
}
// let repolink = {{.RepoLink }}
// $('#benchmark_types_id').change(function () {
// console.log("----")
// // setChildType();
// })
// $("#benchmark_types_id").dropdown({
// onChange:function (value, text, $selectedItem){
// console.log(value)
// }
// })
// $(document).ready(() => {
// $('.ui.search.dropdown.job_type').dropdown({
// onChange: function (value, text, $selectedItem) {
// console.log(value)
// if (value === "BRAINSCORE") {
// $('#brainscore_child_type').css('display', 'block')
// $('#benchmark_model_example').attr('href', 'https://openi.pcl.ac.cn/BDIP/similarity2brain_ann')
// } else {
// $('#brainscore_child_type').css('display', 'none')
// $('#benchmark_model_example').attr('href', 'https://openi.pcl.ac.cn/BDIP/snn4imagenet')
// }
// }
// })
// })
// function setChildType(type_id=1) {
// if (type_id == 3) {
// $('#train_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_MOT_benchmark');
// $('#test_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_MOT_benchmark');
// } else {
// $('#train_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark');
// $('#test_href_id').attr('href', 'https://openi.pcl.ac.cn/CV_benchmark/CV_reID_benchmark');
// }
// let child_selected_id = $('#benchmark_child_types_id_hidden').val();
// $.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => {
// const n_length = data['child_types'].length
// let html = ''
// for (let i = 0; i < n_length; i++) {
// if (child_selected_id == data['child_types'][i].id) {
// html += `<option value="${data['child_types'][i].id}" selected="true">${data['child_types'][i].value}</option>`;
// } else {
// html += `<option value="${data['child_types'][i].id}">${data['child_types'][i].value}</option>`;
// }
// }
// document.getElementById("benchmark_child_types_id").innerHTML = html;
// })
// }
// $(document).ready(function (){
// console.log("00")
// $(".ui.selection.dropdown.benchmark_types_id").dropdown({
// onChange:function (value, text, $selectedItem){
// console.log(value)
// setChildType(value)
// }
// })
// })
// document.onreadystatechange = function () {
// if (document.readyState === "complete") {
// if ($('input[name=benchmarkMode]').val() === 'alogrithm' || $('input[name=benchmarkMode]').val() === '') {
// setChildType();
// }
// }
// }
// var isValidate = false;
// function validate() {
// $('.ui.form')
// .form({
// on: 'blur',
// fields: {
// image: {
// identifier: 'image',
// rules: [
// {
// type: 'empty',
// promt: ''
// }
// ]
// },
// display_job_name: {
// identifier: 'display_job_name',
// rules: [
// {
// type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]',
// promt: ''
// }
// ]
// },
// spec_id: {
// identifier: 'spec_id',
// rules: [{ type: 'empty' }]
// }
// },
// onSuccess: function () {
// // $('.ui.page.dimmer').dimmer('show')
// document.getElementById("mask").style.display = "block"
// isValidate = true;
// },
// onFailure: function (e) {
// isValidate = false;
// return false;
// }
// })
// }

validate()
$('.ui.create_train_job.green.button').click(function (e) {
validate()
})
// validate()
// $('.ui.create_train_job.green.button').click(function (e) {
// validate()
// })

;(function() {
var SPECS = {{ .benchmark_specs }};


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

@@ -206,7 +206,7 @@
<table class="ti-form">
<tbody class="ti-text-form">

{{if eq .JobType "BENCHMARK"}}
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}
@@ -214,11 +214,7 @@

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{if eq .JobType "BENCHMARK"}}
train.py
{{else}}
--
{{end}}
</div>
</td>
</tr>
@@ -228,16 +224,39 @@
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{if eq .JobType "BENCHMARK"}}
test.py
{{else}}
--
{{end}}
</div>
</td>
</tr>
{{else}}
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.model_name"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .ModelName}}{{.ModelName}}{{else}}--{{end}}</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelconvert.modelversion"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .ModelVersion}}{{.ModelVersion}}{{else}}--{{end}}</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.infer_job_model_file"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .CkptName}}{{.CkptName}}{{else}}--{{end}}</div>
</td>
</tr>
{{end}}
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.train_job.description"}}
@@ -271,17 +290,7 @@
<div class="text-span text-span-w"></div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.model_manager"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-mirror">
{{.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.cloudbrain_creator"}}


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

@@ -40,7 +40,7 @@
{{template "base/alert" .}}
{{end}}
{{template "custom/alert_cb" .}}
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div>
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_infer"}}
</h4>


+ 12
- 4
templates/repo/cloudbrain/inference/show.tmpl View File

@@ -371,10 +371,18 @@
<div class="ui tab" data-tab="four">
<input type="hidden" name="model{{.VersionName}}" value="-1">
<input type="hidden" name="modelback{{.VersionName}}" value="-1">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">{{.VersionName}}</div>
<div class="divider"> / </div>

<div style="display: flex;justify-content: space-between;">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">{{.VersionName}}</div>
<div class="divider"> / </div>
</div>
<a id="{{.VersionName}}-result-down" style="padding-right: 1%;display: none;"
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}} file-info'
href="{{$.RepoLink}}/cloudbrain/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.all_result_download"}}</span>
</a>
</div>
<div id="dir_list{{.VersionName}}">



+ 3
- 2
templates/repo/cloudbrain/new.tmpl View File

@@ -23,7 +23,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}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}" data-flag-model="true"></div>
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-flag-model="true" data-dataset-uuid="{{.attachment}}" data-dataset-name="{{.dataset_name}}" data-exceed-size="{{DebugAttachSize}}"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
@@ -38,6 +38,7 @@
<form id="form_id" class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name='isBranches' value="{{.Branches}}">
<input type="hidden" id="ai_image_name" value="{{.image}}">
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
@@ -184,7 +185,7 @@
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:154px;font-size:12px;width:48.5%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>


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

@@ -111,7 +111,9 @@
<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-code">
{{.BranchName}}
{{if not .BootFile}}
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span>
{{end}}
</div>
</td>
</tr>
@@ -376,6 +378,7 @@
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
$('.menu .item').tab()
$(document).ready(function () {
$('.ui.accordion').accordion({ selector: { trigger: '.icon' } });


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

@@ -56,7 +56,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}}" data-flag-model="true" data-dataset-uuid="{{.attachment}}" data-dataset-name="{{.dataset_name}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div>
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-flag-model="true" data-dataset-uuid="{{.attachment}}" data-dataset-name="{{.dataset_name}}"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}


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

@@ -1,5 +1,5 @@
{{template "base/head" .}}
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css">
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css?v={{MD5 AppVer}}" type="text/css">
<style>
.model_file_bread {
margin-bottom: -0.5rem !important;
@@ -123,7 +123,17 @@
</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_creator"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-mirror">
{{.User.Name}}
</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.start_time"}}
@@ -351,9 +361,18 @@
<div class="ui tab" data-tab="four{{$k}}">
<input type="hidden" name="model{{.VersionName}}" value="-1">
<input type="hidden" name="modelback{{.VersionName}}" value="-1">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">result</div>
<div class="divider"> / </div>
<div style="display: flex;justify-content: space-between;">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">result</div>
<div class="divider"> / </div>
</div>
<a id="{{.VersionName}}-result-down" style="padding-right: 1%;display: none;"
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}} file-info'
href="{{$.RepoLink}}/cloudbrain/train-job/{{.JobID}}/download_multi_model?version_name={{.VersionName}}&jobName={{.JobName}}">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.all_result_download"}}</span>
</a>
</div>
<div id="dir_list{{.VersionName}}">
</div>
@@ -495,8 +514,8 @@
</div>
</div>
{{template "base/footer" .}}
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.core.js"></script>
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.js"></script>
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.core.js?v={{MD5 AppVer}}"></script>
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>

<script>


+ 1
- 1
templates/repo/datasets/dirs/dir_list.tmpl View File

@@ -27,7 +27,7 @@
<table id="dataset-files-table" class="ui single line table">
</table>
<script src="{{StaticUrlPrefix}}/self/test.js"></script>
<script src="{{StaticUrlPrefix}}/self/test.js?v={{MD5 AppVer}}"></script>


<script type="text/javascript">


+ 1
- 1
templates/repo/datasets/dirs/dir_preview.tmpl View File

@@ -208,5 +208,5 @@
}
}
</script>
<script src="{{StaticUrlPrefix}}/self/dataset_preview.js"></script>
<script src="{{StaticUrlPrefix}}/self/dataset_preview.js?v={{MD5 AppVer}}"></script>
{{end}}

+ 1
- 1
templates/repo/datasets/label/index.tmpl View File

@@ -215,7 +215,7 @@



<script src="/self/labelTaskPage.js"></script>
<script src="/self/labelTaskPage.js?v={{MD5 AppVer}}"></script>

{{template "base/footer" .}}

+ 1
- 0
templates/repo/debugjob/index.tmpl View File

@@ -152,6 +152,7 @@
<div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div>
<div class="item" data-value="CPU/GPU">CPU/GPU</div>
<div class="item" data-value="NPU">NPU</div>
<div class="item" data-value="GCU">GCU</div>
</div>
</div>
{{if .Permission.CanWrite $.UnitTypeCloudBrain}}


+ 161
- 0
templates/repo/grampus/notebook/gcu/new.tmpl View File

@@ -0,0 +1,161 @@
{{template "base/head" .}}
{{template "custom/global_mask" .}}
<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}}" data-flag-model="true" data-dataset-uuid="{{.attachment}}" data-dataset-name="{{.dataset_name}}" data-exceed-size="{{DebugAttachSize}}"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" id="messageInfo" style="display: none;">
<p></p>
</div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_debug"}}
</h4>
{{template "custom/alert_cb" .}}
<div class="ui attached segment">
<form class="ui form" id="form_id" action="{{.Link}}" method="post">
<input type="hidden" name="type" value="2">
<input type="hidden" name="image" value="">
{{.CsrfTokenHtml}}
<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/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/notebook/create?type=1">
<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="inline required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/grampus/notebook/create?type=0">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/>
</svg>
CPU/GPU</a>
<a class="item" href="{{.RepoLink}}/grampus/notebook/create?type=1">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/>
</svg>
Ascend NPU</a>
<a class="active item" href="{{.RepoLink}}/grampus/notebook/create?type=2">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/>
</svg>
GCU</a>
</div>
</div>
<div class="inline field">
<label class="label-fix-width" style="font-weight: normal;"></label>
{{template "custom/task_wait_count" .}}
<div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;">
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_debug_gpu_tooltips1" "/code" "/dataset" "/pretrainmodel" | Safe}}</span>
</div>
</div>
<div class="inline min_title required field" style="margin-bottom: 0rem !important;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_name"}}</label>
<input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" style="width: 60%;" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="36" onkeyup="this.value=this.value.replace(/[, ]/g,'')">
</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span>
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2 {{if not .Branches}}error{{end}}" 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>
{{template "custom/select_model" .}}
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label>
<select class="ui search dropdown cloudbrain_image width48" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" style='width:385px' name="image_id">
{{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option>
{{end}}
</select>
</div>
<div id="select-multi-dataset">

</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.specification"}}</label>
<select id="__specs__" class="ui search dropdown width48" ovalue="{{.spec_id}}"
{{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="spec_id"></select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:154px;font-size:12px;width:48.5%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
{{end}}
</div>
<div class="inline field">
<label class="label-fix-width" style="font-weight: normal;"></label>
<button class="ui create_train_job green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button cancel" href="{{.RepoLink}}/debugjob?debugListType=all">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
</form>
</div>
</div>
</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
;(function() {
var SPECS = {{ .Specs }};
var showPoint = {{ .CloudBrainPaySwitch }};
window.renderSpecsSelect($('#__specs__'), SPECS, showPoint, {
gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}},
free: {{$.i18n.Tr "cloudbrain.free"}},
point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}},
memory: {{$.i18n.Tr "cloudbrain.memory"}},
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}},
});
})();
</script>

+ 12
- 5
templates/repo/grampus/notebook/gpu/new.tmpl View File

@@ -4,8 +4,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}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}" data-flag-model="true"></div>
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-flag-model="true" data-dataset-uuid="{{.attachment}}" data-dataset-name="{{.dataset_name}}" data-exceed-size="{{DebugAttachSize}}"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
@@ -20,8 +19,8 @@
<form id="form_id" class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="type" value="0">
<input type="hidden" id="ai_image_name" value="{{.image}}">
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required 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">
@@ -55,6 +54,14 @@
d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" />
</svg>
Ascend NPU</a>
<a class="item" href="{{.RepoLink}}/grampus/notebook/create?type=2">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16"
height="16">
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" />
</svg>
GCU</a>
</div>
</div>
<div class="min_title inline field">
@@ -120,7 +127,7 @@
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:154px;font-size:12px;width:48.5%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
@@ -148,7 +155,7 @@
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
<script>
;(function() {
var SPECS = {{ .Specs }};
var showPoint = {{ .CloudBrainPaySwitch }};


+ 24
- 5
templates/repo/grampus/notebook/npu/new.tmpl View File

@@ -3,7 +3,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}}" data-flag-model="true"></div>
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-flag-model="true" data-dataset-uuid="{{.attachment}}" data-dataset-name="{{.dataset_name}}" data-exceed-size="{{DebugAttachSize}}"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
@@ -48,6 +48,12 @@
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/>
</svg>
Ascend NPU</a>
<a class="item" href="{{.RepoLink}}/grampus/notebook/create?type=2">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/>
</svg>
GCU</a>
</div>
</div>
<div class="inline field">
@@ -93,8 +99,21 @@
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label>
<select class="ui search dropdown cloudbrain_image width48" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" style='width:385px' name="image_id">
{{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option>
{{if .image_id}}
{{range .images}}
{{if eq $.image_id .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{range .images}}
{{if ne $.image_id .ID}}
<option value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
{{else}}
{{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option>
{{end}}
{{end}}
</select>
</div>
@@ -111,7 +130,7 @@
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:154px;font-size:12px;width:48.5%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
@@ -136,7 +155,7 @@
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
<script>
;(function() {
var SPECS = {{ .Specs }};
var showPoint = {{ .CloudBrainPaySwitch }};


+ 26
- 7
templates/repo/grampus/trainjob/show.tmpl View File

@@ -1,5 +1,5 @@
{{template "base/head" .}}
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css">
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css?v={{MD5 AppVer}}" type="text/css">
<style>
.model_file_bread {
margin-bottom: -0.5rem !important;
@@ -121,6 +121,17 @@
</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_creator"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-mirror">
{{.User.Name}}
</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.run_version"}}
@@ -386,10 +397,18 @@
<div class="ui tab" data-tab="third{{$k}}">
<input type="hidden" name="model{{.VersionName}}" value="-1">
<input type="hidden" name="modelback{{.VersionName}}" value="-1">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">{{.VersionName}}</div>
<div class="divider"> / </div>

<div style="display: flex;justify-content: space-between;">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">{{.VersionName}}</div>
<div class="divider"> / </div>
</div>
<a id="{{.VersionName}}-result-down" style="padding-right: 1%;display: none;"
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}} file-info'
href="{{$.RepoLink}}/grampus/train-job/{{.JobID}}/download_multi_model?version_name={{.VersionName}}">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.all_result_download"}}</span>
</a>
</div>
<div id="dir_list{{.VersionName}}">
</div>
@@ -534,8 +553,8 @@

</div>
{{template "base/footer" .}}
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.core.js"></script>
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.js"></script>
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.core.js?v={{MD5 AppVer}}"></script>
<script type="text/javascript" src="/self/ztree/js/jquery.ztree.excheck.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
;(function() {


+ 11
- 11
templates/repo/header.tmpl View File

@@ -225,14 +225,14 @@


<script src="{{StaticUrlPrefix}}/js/jquery.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/es5-shim.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/marked.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/purify.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/ansi_up.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/prism.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/katex.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/katex-auto-render.min.js"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/notebook.min.js"></script>
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/katex.min.css" />
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/prism.css" />
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/notebook.css" />
<script src="{{StaticUrlPrefix}}/self/js/notebook/es5-shim.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/marked.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/purify.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/ansi_up.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/prism.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/katex.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/katex-auto-render.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/self/js/notebook/notebook.min.js?v={{MD5 AppVer}}"></script>
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/katex.min.css?v={{MD5 AppVer}}" />
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/prism.css?v={{MD5 AppVer}}" />
<link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/notebook.css?v={{MD5 AppVer}}" />

+ 5
- 5
templates/repo/home.tmpl View File

@@ -311,7 +311,7 @@
<div class="ui six wide tablet four wide computer column">
<div id="repo-desc" data-IsAdmin="{{.Permission.IsAdmin}}"
data-IsArchived="{{.Repository.IsArchived}}">
<h4 id="about-desc" class="ui header">简介</h4>
<h4 id="about-desc" class="ui header"></h4>
<input type="hidden" id="edit-alias" value="{{.Repository.Alias}}">
<p>
{{if .Repository.DescriptionHTML}}
@@ -363,15 +363,15 @@
<h4 class="ui header">
{{$lenCon := len .ContributorInfo}}
{{if lt $lenCon 25 }}
<strong>贡献者 ({{len .ContributorInfo}})</strong>
<strong>{{.i18n.Tr "home.contributors"}} ({{len .ContributorInfo}})</strong>
{{else}}
<strong>贡献者 ({{len .ContributorInfo}}+)</strong>
<strong>{{.i18n.Tr "home.contributors"}} ({{len .ContributorInfo}}+)</strong>
{{end}}

<div class="ui right">
<!-- <a class="membersmore text grey" href="{{.RepoLink}}/contributors">全部 {{svg "octicon-chevron-right" 16}}</a> -->
<!-- <a class="membersmore text grey" href="{{.RepoLink}}/contributors">{{.i18n.Tr "repo.computing.all"}} {{svg "octicon-chevron-right" 16}}</a> -->
<a class="membersmore text grey"
href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">全部
href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">{{.i18n.Tr "repo.computing.all"}}
{{svg "octicon-chevron-right" 16}}</a>
</div>
</h4>


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save