Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/2836tags/v1.22.8.2
@@ -713,12 +713,14 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 | |||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= | |||
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= | |||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= | |||
github.com/smartystreets/assertions v1.1.0 h1:MkTeG1DMwsrdH7QtLXy5W+fUxWq+vmb6cLmyJ7aRtF0= | |||
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= | |||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= | |||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= | |||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | |||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= | |||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | |||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= | |||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | |||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= | |||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= | |||
@@ -0,0 +1,49 @@ | |||
package models | |||
import ( | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"encoding/json" | |||
) | |||
type AdminOperateLog struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
BizType string | |||
OperateType string | |||
OldValue string `xorm:"TEXT"` | |||
NewValue string `xorm:"TEXT"` | |||
RelatedId string `xorm:"INDEX"` | |||
Comment string | |||
CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
CreatedBy int64 | |||
} | |||
type LogValues struct { | |||
Params []LogValue | |||
} | |||
type LogValue struct { | |||
Key string | |||
Val interface{} | |||
} | |||
func (l *LogValues) Add(key string, val interface{}) *LogValues { | |||
l.Params = append(l.Params, LogValue{Key: key, Val: val}) | |||
return l | |||
} | |||
func (l *LogValues) JsonString() string { | |||
if len(l.Params) == 0 { | |||
return "" | |||
} | |||
b, err := json.Marshal(l) | |||
if err != nil { | |||
log.Error("LogValues JsonString error . %v", err) | |||
return "" | |||
} | |||
return string(b) | |||
} | |||
func InsertAdminOperateLog(log AdminOperateLog) (int64, error) { | |||
return x.Insert(&log) | |||
} |
@@ -8,13 +8,14 @@ import ( | |||
"strings" | |||
"time" | |||
"code.gitea.io/gitea/modules/util" | |||
"xorm.io/builder" | |||
"xorm.io/xorm" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"code.gitea.io/gitea/modules/util" | |||
) | |||
type CloudbrainStatus string | |||
@@ -30,9 +31,9 @@ const ( | |||
) | |||
const ( | |||
NPUResource = "NPU" | |||
GPUResource = "CPU/GPU" | |||
AllResource = "all" | |||
NPUResource = "NPU" | |||
GPUResource = "CPU/GPU" | |||
AllResource = "all" | |||
//notebook storage category | |||
EVSCategory = "EVS" | |||
@@ -70,6 +71,7 @@ const ( | |||
ModelArtsStopping ModelArtsJobStatus = "STOPPING" //停止中 | |||
ModelArtsStopped ModelArtsJobStatus = "STOPPED" //停止 | |||
ModelArtsUnavailable ModelArtsJobStatus = "UNAVAILABLE" //故障 | |||
ModelArtsDeleting ModelArtsJobStatus = "DELETING" //删除中 | |||
ModelArtsDeleted ModelArtsJobStatus = "DELETED" //已删除 | |||
ModelArtsResizing ModelArtsJobStatus = "RESIZING" //规格变更中 | |||
ModelArtsResizFailed ModelArtsJobStatus = "RESIZE_FAILED" //规格变更失败 | |||
@@ -110,6 +112,16 @@ const ( | |||
GrampusStatusWaiting = "WAITING" | |||
) | |||
const ( | |||
//cluster | |||
OpenICluster = "OpenI" | |||
C2NetCluster = "C2Net" | |||
//AI center | |||
AICenterOfCloudBrainOne = "OpenIOne" | |||
AICenterOfCloudBrainTwo = "OpenITwo" | |||
) | |||
type Cloudbrain struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
JobID string `xorm:"INDEX NOT NULL"` | |||
@@ -142,7 +154,7 @@ type Cloudbrain struct { | |||
VersionID int64 //版本id | |||
VersionName string `xorm:"INDEX"` //当前版本 | |||
Uuid string //数据集id | |||
DatasetName string | |||
DatasetName string `xorm:"varchar(2000)"` | |||
VersionCount int //任务的当前版本数量,不包括删除的 | |||
IsLatestVersion string //是否是最新版本,1是,0否 | |||
CommitID string //提交的仓库代码id | |||
@@ -1081,6 +1093,7 @@ type DatasetDownload struct { | |||
DatasetName string `json:"dataset_name"` | |||
DatasetDownloadLink string `json:"dataset_download_link"` | |||
RepositoryLink string `json:"repository_link"` | |||
IsDelete bool `json:"is_delete"` | |||
} | |||
type DataSource struct { | |||
@@ -1337,6 +1350,34 @@ type GrampusSpec struct { | |||
Name string `json:"name"` | |||
ProcessorType string `json:"processorType"` | |||
Centers []Center `json:"centers"` | |||
SpecInfo SpecInfo `json:"specInfo"` | |||
} | |||
type GrampusAiCenter struct { | |||
AccDevices []GrampusAccDevice `json:"accDevices"` | |||
Id string `json:"id"` | |||
Name string `json:"name"` | |||
Resource []GrampusCenterResource `json:"resource"` | |||
} | |||
type GrampusAccDevice struct { | |||
Kind string `json:"kind"` //加速卡类别, npu.huawei.com/NPU,nvidia.com/gpu,cambricon.com/mlu | |||
Model string `json:"model"` //加速卡型号 | |||
} | |||
type GrampusCenterResource struct { | |||
Allocated string `json:"allocated"` | |||
Capacity string `json:"capacity"` | |||
Name string `json:"name"` | |||
} | |||
type SpecInfo struct { | |||
AccDeviceKind string `json:"accDeviceKind"` | |||
AccDeviceMemory string `json:"accDeviceMemory"` | |||
AccDeviceModel string `json:"accDeviceModel"` | |||
AccDeviceNum int `json:"accDeviceNum"` | |||
CpuCoreNum int `json:"cpuCoreNum"` | |||
MemorySize string `json:"memorySize"` | |||
} | |||
type GetGrampusResourceSpecsResult struct { | |||
@@ -1344,6 +1385,12 @@ type GetGrampusResourceSpecsResult struct { | |||
Infos []GrampusSpec `json:"resourceSpecs"` | |||
} | |||
type GetGrampusAiCentersResult struct { | |||
GrampusResult | |||
Infos []GrampusAiCenter `json:"aiCenterInfos"` | |||
TotalSize int `json:"totalSize"` | |||
} | |||
type GrampusImage struct { | |||
CreatedAt int64 `json:"createdAt"` | |||
UpdatedAt int64 `json:"updatedAt"` | |||
@@ -1767,6 +1814,12 @@ func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) { | |||
return cloudBrains, err | |||
} | |||
func GetCloudbrainsNeededDeleteByRepoID(repoID int64) ([]*Cloudbrain, error) { | |||
cloudBrains := make([]*Cloudbrain, 0) | |||
err := x.Where("repo_id=?", repoID).Find(&cloudBrains) | |||
return cloudBrains, err | |||
} | |||
func GetCloudbrainsByDisplayJobName(repoID int64, jobType string, displayJobName string) ([]*Cloudbrain, error) { | |||
cloudBrains := make([]*Cloudbrain, 0) | |||
err := x.Cols("job_id", "job_name", "repo_id", "user_id", "job_type", "display_job_name").Where("repo_id=? AND job_type =? AND lower(display_job_name) = lower(?)", repoID, jobType, displayJobName).Find(&cloudBrains) | |||
@@ -1882,9 +1935,9 @@ func GetCloudbrainCountByUserID(userID int64, jobType string) (int, error) { | |||
func GetCloudbrainRunCountByRepoID(repoID int64) (int, error) { | |||
count, err := x.In("status", JobWaiting, JobRunning, ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting, | |||
ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsRestarting, ModelArtsTrainJobInit, | |||
ModelArtsTrainJobImageCreating, ModelArtsTrainJobSubmitTrying, ModelArtsTrainJobWaiting, ModelArtsTrainJobRunning, | |||
ModelArtsTrainJobScaling, ModelArtsTrainJobCheckInit, ModelArtsTrainJobCheckRunning, ModelArtsTrainJobCheckRunningCompleted).And("repo_id = ?", repoID).Count(new(Cloudbrain)) | |||
ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsDeleting, ModelArtsRestarting, ModelArtsTrainJobInit, | |||
ModelArtsTrainJobImageCreating, ModelArtsTrainJobSubmitTrying, ModelArtsTrainJobWaiting, ModelArtsTrainJobRunning, ModelArtsStopping, ModelArtsResizing, | |||
ModelArtsTrainJobScaling, ModelArtsTrainJobCheckInit, ModelArtsTrainJobCheckRunning, ModelArtsTrainJobKilling, ModelArtsTrainJobCheckRunningCompleted).And("repo_id = ?", repoID).Count(new(Cloudbrain)) | |||
return int(count), err | |||
} | |||
@@ -2173,7 +2226,18 @@ func GetDatasetInfo(uuidStr string) (map[string]DatasetInfo, string, error) { | |||
log.Error("GetAttachmentsByUUIDs failed: %v", err) | |||
return nil, datasetNames, err | |||
} | |||
for i, attach := range attachs { | |||
for i, tmpUuid := range uuids { | |||
var attach *Attachment | |||
for _, tmpAttach := range attachs { | |||
if tmpAttach.UUID == tmpUuid { | |||
attach = tmpAttach | |||
break | |||
} | |||
} | |||
if attach == nil { | |||
log.Error("GetAttachmentsByUUIDs failed: %v", err) | |||
return nil, datasetNames, err | |||
} | |||
fileName := strings.TrimSuffix(strings.TrimSuffix(strings.TrimSuffix(attach.Name, ".zip"), ".tar.gz"), ".tgz") | |||
for _, datasetInfo := range datasetInfos { | |||
if fileName == datasetInfo.Name { | |||
@@ -518,6 +518,10 @@ func UpdateLocalImageStatus(image *Image) error { | |||
return err | |||
} | |||
func UpdateAutoIncrementIndex() { | |||
x.Exec("SELECT setval('image_id_seq', (SELECT MAX(id) from image))") | |||
} | |||
func DeleteLocalImage(id int64) error { | |||
image := new(Image) | |||
_, err := x.ID(id).Delete(image) | |||
@@ -6,6 +6,8 @@ import ( | |||
"sort" | |||
"strings" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
@@ -88,7 +90,7 @@ func (datasets DatasetList) loadAttributes(e Engine) error { | |||
if err := e. | |||
Where("id > 0"). | |||
In("id", keysInt64(set)). | |||
Cols("id", "owner_id", "owner_name", "lower_name", "name", "description", "alias", "lower_alias","is_private"). | |||
Cols("id", "owner_id", "owner_name", "lower_name", "name", "description", "alias", "lower_alias", "is_private"). | |||
Find(&repos); err != nil { | |||
return fmt.Errorf("find repos: %v", err) | |||
} | |||
@@ -119,14 +121,16 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions) | |||
for i := range datasets { | |||
if attachment.DatasetID == datasets[i].ID { | |||
if opts.StarByMe { | |||
permission,ok := permissionMap[datasets[i].ID]; | |||
if !attachment.IsPrivate{ | |||
datasets[i].Attachments = append(datasets[i].Attachments, attachment) | |||
}else{ | |||
permission, ok := permissionMap[datasets[i].ID] | |||
if !ok { | |||
permission = false | |||
datasets[i].Repo.GetOwner() | |||
if datasets[i].Repo.Owner.IsOrganization() { | |||
if datasets[i].Repo.Owner.IsOrganization() { | |||
if datasets[i].Repo.Owner.IsUserPartOfOrg(opts.User.ID) { | |||
log.Info("user is member of org.") | |||
permission = true | |||
@@ -134,22 +138,18 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions) | |||
} | |||
if !permission { | |||
isCollaborator, _ := datasets[i].Repo.IsCollaborator(opts.User.ID) | |||
if isCollaborator { | |||
if isCollaborator ||datasets[i].Repo.IsOwnedBy(opts.User.ID){ | |||
log.Info("Collaborator user may visit the attach.") | |||
permission = true | |||
} | |||
} | |||
permissionMap[datasets[i].ID]=permission | |||
permissionMap[datasets[i].ID] = permission | |||
} | |||
if permission{ | |||
datasets[i].Attachments = append(datasets[i].Attachments, attachment) | |||
} else if !attachment.IsPrivate { | |||
if permission { | |||
datasets[i].Attachments = append(datasets[i].Attachments, attachment) | |||
} | |||
} else { | |||
datasets[i].Attachments = append(datasets[i].Attachments, attachment) | |||
} | |||
} | |||
@@ -159,8 +159,8 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions) | |||
} | |||
for i := range datasets { | |||
if datasets[i].Attachments==nil{ | |||
datasets[i].Attachments=[]*Attachment{} | |||
if datasets[i].Attachments == nil { | |||
datasets[i].Attachments = []*Attachment{} | |||
} | |||
datasets[i].Repo.Owner = nil | |||
} | |||
@@ -169,16 +169,17 @@ func (datasets DatasetList) loadAttachmentAttributes(opts *SearchDatasetOptions) | |||
} | |||
type SearchDatasetOptions struct { | |||
Keyword string | |||
OwnerID int64 | |||
User *User | |||
RepoID int64 | |||
IncludePublic bool | |||
RecommendOnly bool | |||
Category string | |||
Task string | |||
License string | |||
DatasetIDs []int64 // 目前只在StarByMe为true时起作用 | |||
Keyword string | |||
OwnerID int64 | |||
User *User | |||
RepoID int64 | |||
IncludePublic bool | |||
RecommendOnly bool | |||
Category string | |||
Task string | |||
License string | |||
DatasetIDs []int64 | |||
ExcludeDatasetId int64 | |||
ListOptions | |||
SearchOrderBy | |||
IsOwner bool | |||
@@ -188,6 +189,7 @@ type SearchDatasetOptions struct { | |||
JustNeedZipFile bool | |||
NeedAttachment bool | |||
UploadAttachmentByMe bool | |||
QueryReference bool | |||
} | |||
func CreateDataset(dataset *Dataset) (err error) { | |||
@@ -237,6 +239,10 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond { | |||
cond = cond.And(builder.Eq{"dataset.repo_id": opts.RepoID}) | |||
} | |||
if opts.ExcludeDatasetId > 0 { | |||
cond = cond.And(builder.Neq{"dataset.id": opts.ExcludeDatasetId}) | |||
} | |||
if opts.PublicOnly { | |||
cond = cond.And(builder.Eq{"dataset.status": DatasetStatusPublic}) | |||
cond = cond.And(builder.Eq{"attachment.is_private": false}) | |||
@@ -258,7 +264,7 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond { | |||
} | |||
} | |||
if len(opts.DatasetIDs) > 0 { | |||
if opts.StarByMe { | |||
if opts.StarByMe || (opts.RepoID == 0 && opts.QueryReference) { | |||
cond = cond.And(builder.In("dataset.id", opts.DatasetIDs)) | |||
} else { | |||
subCon := builder.NewCond() | |||
@@ -329,13 +335,15 @@ func SearchDatasetByCondition(opts *SearchDatasetOptions, cond builder.Cond) (Da | |||
return nil, 0, fmt.Errorf("Count: %v", err) | |||
} | |||
sess.Select(selectColumnsSql).Join("INNER", "repository", "repository.id = dataset.repo_id"). | |||
builderQuery := builder.Dialect(setting.Database.Type).Select("id", "title", "status", "category", "description", "download_times", "license", "task", "release_id", "user_id", "repo_id", "created_unix", "updated_unix", "num_stars", "recommend", "use_count").From(builder.Dialect(setting.Database.Type).Select(selectColumnsSql).From("dataset").Join("INNER", "repository", "repository.id = dataset.repo_id"). | |||
Join("INNER", "attachment", "attachment.dataset_id=dataset.id"). | |||
Where(cond).OrderBy(opts.SearchOrderBy.String()) | |||
Where(cond), "d").OrderBy(opts.SearchOrderBy.String()) | |||
if opts.PageSize > 0 { | |||
sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | |||
builderQuery.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | |||
} | |||
if err = sess.Find(&datasets); err != nil { | |||
if err = sess.SQL(builderQuery).Find(&datasets); err != nil { | |||
return nil, 0, fmt.Errorf("Dataset: %v", err) | |||
} | |||
@@ -585,3 +593,13 @@ func GetTeamDatasetIdsByUserID(userID int64) []int64 { | |||
Cols("dataset.id").Find(&datasets) | |||
return datasets | |||
} | |||
func UpdateDatasetCreateUser(ID int64, user *User) error { | |||
_, err := x.Where("id = ?", ID).Cols("user_id").Update(&Dataset{ | |||
UserID: user.ID, | |||
}) | |||
if err != nil { | |||
return err | |||
} | |||
return nil | |||
} |
@@ -0,0 +1,88 @@ | |||
package models | |||
import ( | |||
"strconv" | |||
"strings" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
) | |||
type DatasetReference struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
RepoID int64 `xorm:"INDEX unique"` | |||
DatasetID string `xorm:"TEXT"` | |||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||
} | |||
func GetDatasetIdsByRepoID(repoID int64) []int64 { | |||
var datasets []int64 | |||
var datasetIds []string | |||
_ = x.Table("dataset_reference").Where("repo_id=?", repoID). | |||
Cols("dataset_reference.dataset_id").Find(&datasetIds) | |||
if len(datasetIds) > 0 { | |||
for _, datasetIdStr := range strings.Split(datasetIds[0], ",") { | |||
datasetId, err := strconv.ParseInt(datasetIdStr, 10, 64) | |||
if err != nil { | |||
continue | |||
} | |||
datasets = append(datasets, datasetId) | |||
} | |||
} | |||
return datasets | |||
} | |||
func HasReferenceDataset(repoID int64) bool { | |||
var datasetIds []string | |||
_ = x.Table("dataset_reference").Where("repo_id=?", repoID). | |||
Cols("dataset_reference.dataset_id").Find(&datasetIds) | |||
return len(datasetIds) > 0 | |||
} | |||
func getReferenceDatasetStr(repoID int64) string { | |||
var datasetIds []string | |||
_ = x.Table("dataset_reference").Where("repo_id=?", repoID). | |||
Cols("dataset_reference.dataset_id").Find(&datasetIds) | |||
if len(datasetIds) > 0 { | |||
return datasetIds[0] | |||
} | |||
return "" | |||
} | |||
func DeleteReferenceDatasetIdsByRepoID(repoID int64) error { | |||
_, err := x.Exec("delete from dataset_reference where repo_id=?", repoID) | |||
return err | |||
} | |||
func NewDatasetIdsByRepoID(repoID int64, datasetIds []int64) error { | |||
if len(datasetIds) == 0 { //关联数据集数组为空 | |||
DeleteReferenceDatasetIdsByRepoID(repoID) | |||
} | |||
var datasetsStrArray []string | |||
for _, datasetId := range datasetIds { | |||
datasetsStrArray = append(datasetsStrArray, strconv.FormatInt(datasetId, 10)) | |||
} | |||
newDatasetStr := strings.Join(datasetsStrArray, ",") | |||
oldDatasetStr := getReferenceDatasetStr(repoID) | |||
if newDatasetStr == oldDatasetStr { //关联数据集无变化,不需要处理 | |||
return nil | |||
} | |||
if oldDatasetStr != "" { //已经存在关联数据集 | |||
_, err := x.Exec("update dataset_reference set dataset_id=? where repo_id=?", newDatasetStr, repoID) | |||
return err | |||
} else { | |||
datasetReference := DatasetReference{ | |||
DatasetID: newDatasetStr, | |||
RepoID: repoID, | |||
} | |||
_, err := x.Insert(datasetReference) | |||
return err | |||
} | |||
} |
@@ -145,7 +145,13 @@ func init() { | |||
new(OrgStatistic), | |||
new(SearchRecord), | |||
new(AiModelConvert), | |||
new(ResourceQueue), | |||
new(ResourceSpecification), | |||
new(ResourceScene), | |||
new(ResourceSceneSpec), | |||
new(AdminOperateLog), | |||
new(CloudbrainTemp), | |||
new(DatasetReference), | |||
) | |||
tablesStatistic = append(tablesStatistic, | |||
@@ -1788,7 +1788,6 @@ func DeleteRepository(doer *User, uid, repoID int64) error { | |||
// Delete dataset attachment record and remove related files | |||
deleteDatasetAttachmentByRepoId(sess, repoID) | |||
if err = deleteBeans(sess, | |||
&Access{RepoID: repo.ID}, | |||
&Action{RepoID: repo.ID}, | |||
@@ -0,0 +1,349 @@ | |||
package models | |||
import ( | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"errors" | |||
"strconv" | |||
"strings" | |||
"xorm.io/builder" | |||
) | |||
type ResourceQueue struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
QueueCode string | |||
Cluster string `xorm:"notnull"` | |||
AiCenterCode string | |||
AiCenterName string | |||
ComputeResource string | |||
AccCardType string | |||
CardsTotalNum int | |||
IsAutomaticSync bool | |||
Remark string | |||
DeletedTime timeutil.TimeStamp `xorm:"deleted"` | |||
CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
CreatedBy int64 | |||
UpdatedTime timeutil.TimeStamp `xorm:"updated"` | |||
UpdatedBy int64 | |||
} | |||
func (r ResourceQueue) ConvertToRes() *ResourceQueueRes { | |||
return &ResourceQueueRes{ | |||
ID: r.ID, | |||
QueueCode: r.QueueCode, | |||
Cluster: r.Cluster, | |||
AiCenterCode: r.AiCenterCode, | |||
AiCenterName: r.AiCenterName, | |||
ComputeResource: r.ComputeResource, | |||
AccCardType: r.AccCardType, | |||
CardsTotalNum: r.CardsTotalNum, | |||
UpdatedTime: r.UpdatedTime, | |||
Remark: r.Remark, | |||
} | |||
} | |||
type ResourceQueueReq struct { | |||
QueueCode string | |||
Cluster string `binding:"Required"` | |||
AiCenterCode string | |||
ComputeResource string `binding:"Required"` | |||
AccCardType string `binding:"Required"` | |||
CardsTotalNum int | |||
CreatorId int64 | |||
IsAutomaticSync bool | |||
Remark string | |||
} | |||
func (r ResourceQueueReq) ToDTO() ResourceQueue { | |||
q := ResourceQueue{ | |||
QueueCode: r.QueueCode, | |||
Cluster: r.Cluster, | |||
AiCenterCode: r.AiCenterCode, | |||
ComputeResource: strings.ToUpper(r.ComputeResource), | |||
AccCardType: strings.ToUpper(r.AccCardType), | |||
CardsTotalNum: r.CardsTotalNum, | |||
IsAutomaticSync: r.IsAutomaticSync, | |||
Remark: r.Remark, | |||
CreatedBy: r.CreatorId, | |||
UpdatedBy: r.CreatorId, | |||
} | |||
if r.Cluster == OpenICluster { | |||
if r.AiCenterCode == AICenterOfCloudBrainOne { | |||
q.AiCenterName = "云脑一" | |||
} else if r.AiCenterCode == AICenterOfCloudBrainTwo { | |||
q.AiCenterName = "云脑二" | |||
} | |||
} | |||
return q | |||
} | |||
type SearchResourceQueueOptions struct { | |||
ListOptions | |||
Cluster string | |||
AiCenterCode string | |||
ComputeResource string | |||
AccCardType string | |||
} | |||
type ResourceQueueListRes struct { | |||
TotalSize int64 | |||
List []*ResourceQueueRes | |||
} | |||
type ResourceQueueCodesRes struct { | |||
ID int64 | |||
QueueCode string | |||
Cluster string | |||
AiCenterCode string | |||
AiCenterName string | |||
} | |||
func (ResourceQueueCodesRes) TableName() string { | |||
return "resource_queue" | |||
} | |||
type ResourceAiCenterRes struct { | |||
AiCenterCode string | |||
AiCenterName string | |||
} | |||
type GetQueueCodesOptions struct { | |||
Cluster string | |||
} | |||
func NewResourceQueueListRes(totalSize int64, list []ResourceQueue) *ResourceQueueListRes { | |||
resList := make([]*ResourceQueueRes, len(list)) | |||
for i, v := range list { | |||
resList[i] = v.ConvertToRes() | |||
} | |||
return &ResourceQueueListRes{ | |||
TotalSize: totalSize, | |||
List: resList, | |||
} | |||
} | |||
type ResourceQueueRes struct { | |||
ID int64 | |||
QueueCode string | |||
Cluster string | |||
AiCenterCode string | |||
AiCenterName string | |||
ComputeResource string | |||
AccCardType string | |||
CardsTotalNum int | |||
UpdatedTime timeutil.TimeStamp | |||
Remark string | |||
} | |||
func InsertResourceQueue(queue ResourceQueue) (int64, error) { | |||
return x.Insert(&queue) | |||
} | |||
func UpdateResourceQueueById(queueId int64, queue ResourceQueue) (int64, error) { | |||
return x.ID(queueId).Update(&queue) | |||
} | |||
func SearchResourceQueue(opts SearchResourceQueueOptions) (int64, []ResourceQueue, error) { | |||
var cond = builder.NewCond() | |||
if opts.Page <= 0 { | |||
opts.Page = 1 | |||
} | |||
if opts.Cluster != "" { | |||
cond = cond.And(builder.Eq{"cluster": opts.Cluster}) | |||
} | |||
if opts.AiCenterCode != "" { | |||
cond = cond.And(builder.Eq{"ai_center_code": opts.AiCenterCode}) | |||
} | |||
if opts.ComputeResource != "" { | |||
cond = cond.And(builder.Eq{"compute_resource": opts.ComputeResource}) | |||
} | |||
if opts.AccCardType != "" { | |||
cond = cond.And(builder.Eq{"acc_card_type": opts.AccCardType}) | |||
} | |||
n, err := x.Where(cond).Unscoped().Count(&ResourceQueue{}) | |||
if err != nil { | |||
return 0, nil, err | |||
} | |||
r := make([]ResourceQueue, 0) | |||
err = x.Where(cond).Desc("id").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Unscoped().Find(&r) | |||
if err != nil { | |||
return 0, nil, err | |||
} | |||
return n, r, nil | |||
} | |||
func GetResourceQueueCodes(opts GetQueueCodesOptions) ([]*ResourceQueueCodesRes, error) { | |||
cond := builder.NewCond() | |||
if opts.Cluster != "" { | |||
cond = cond.And(builder.Eq{"cluster": opts.Cluster}) | |||
} | |||
cond = cond.And(builder.Or(builder.IsNull{"deleted_time"}, builder.Eq{"deleted_time": 0})) | |||
r := make([]*ResourceQueueCodesRes, 0) | |||
err := x.Where(cond).OrderBy("cluster desc,ai_center_code asc").Find(&r) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return r, nil | |||
} | |||
func GetResourceQueue(r *ResourceQueue) (*ResourceQueue, error) { | |||
has, err := x.Get(r) | |||
if err != nil { | |||
return nil, err | |||
} else if !has { | |||
return nil, nil | |||
} | |||
return r, nil | |||
} | |||
func ParseComputeResourceFormGrampus(grampusDeviceKind string) string { | |||
t := strings.Split(grampusDeviceKind, "/") | |||
if len(t) < 2 { | |||
return "" | |||
} | |||
return strings.ToUpper(t[1]) | |||
} | |||
type MemSize struct { | |||
Sizes []string | |||
Hex int | |||
} | |||
var memSize = MemSize{Sizes: []string{"K", "M", "G", "T", "P", "E"}, Hex: 1000} | |||
var iMemSize = MemSize{Sizes: []string{"Ki", "Mi", "Gi", "Ti", "Pi", "Ei"}, Hex: 1024} | |||
func MatchMemSize(memSize MemSize, val string) (int, float32, error) { | |||
for i, v := range memSize.Sizes { | |||
if strings.HasSuffix(val, v) { | |||
s := strings.TrimSuffix(val, v) | |||
f, err := strconv.ParseFloat(s, 32) | |||
if err != nil { | |||
return 0, 0, err | |||
} | |||
return i, float32(f), nil | |||
} | |||
} | |||
return -1, 0, nil | |||
} | |||
//TransferMemSize transfer oldValue format from old index to new index | |||
//eg: memSize.Sizes = []string{"M", "G", "T", "P", "E"}, oldValue = 10 , oldIndex = 1 , newIndex = 0. it means transfer 10G to 10000M | |||
//so it returns 10000 | |||
func TransferMemSize(memSize MemSize, oldValue float32, oldIndex int, newIndex int) float32 { | |||
diff := oldIndex - newIndex | |||
r := oldValue | |||
if diff > 0 { | |||
r = oldValue * float32(diff) * float32(memSize.Hex) | |||
} else if diff < 0 { | |||
r = oldValue / float32(-1*diff) / float32(memSize.Hex) | |||
} | |||
return r | |||
} | |||
//ParseMemSize find the memSize which matches value's format,and parse the number from value | |||
func ParseMemSize(value string, memSize MemSize, newIndex int) (bool, float32, error) { | |||
index, r, err := MatchMemSize(memSize, value) | |||
if err != nil { | |||
return false, 0, err | |||
} | |||
if index < 0 { | |||
return false, 0, nil | |||
} | |||
return true, TransferMemSize(memSize, r, index, newIndex), nil | |||
} | |||
func ParseMemSizeFromGrampus(grampusMemSize string) (float32, error) { | |||
if grampusMemSize == "" { | |||
return 0, nil | |||
} | |||
memflag, memResult, err := ParseMemSize(grampusMemSize, memSize, 2) | |||
if err != nil { | |||
return 0, err | |||
} | |||
if memflag { | |||
return memResult, nil | |||
} | |||
iMemFlag, imemResult, err := ParseMemSize(grampusMemSize, iMemSize, 2) | |||
if err != nil { | |||
return 0, err | |||
} | |||
if iMemFlag { | |||
return imemResult, nil | |||
} | |||
return 0, errors.New("grampus memSize format error") | |||
} | |||
func SyncGrampusQueues(updateList []ResourceQueue, insertList []ResourceQueue, existIds []int64) error { | |||
sess := x.NewSession() | |||
var err error | |||
defer func() { | |||
if err != nil { | |||
sess.Rollback() | |||
} | |||
sess.Close() | |||
}() | |||
//delete queues that no longer exists | |||
deleteQueueIds := make([]int64, 0) | |||
queueCond := builder.NewCond() | |||
queueCond = queueCond.And(builder.NotIn("resource_queue.id", existIds)).And(builder.Eq{"resource_queue.cluster": C2NetCluster}) | |||
if err := sess.Cols("resource_queue.id").Table("resource_queue"). | |||
Where(queueCond).Find(&deleteQueueIds); err != nil { | |||
return err | |||
} | |||
if len(deleteQueueIds) > 0 { | |||
if _, err = sess.In("id", deleteQueueIds).Update(&ResourceQueue{Remark: "自动同步时被下架"}); err != nil { | |||
return err | |||
} | |||
if _, err = sess.In("id", deleteQueueIds).Delete(&ResourceQueue{}); err != nil { | |||
return err | |||
} | |||
//delete specs and scene that no longer exists | |||
deleteSpcIds := make([]int64, 0) | |||
if err := sess.Cols("resource_specification.id").Table("resource_specification"). | |||
In("queue_id", deleteQueueIds).Find(&deleteSpcIds); err != nil { | |||
return err | |||
} | |||
if len(deleteSpcIds) > 0 { | |||
if _, err = sess.In("id", deleteSpcIds).Update(&ResourceSpecification{Status: SpecOffShelf}); err != nil { | |||
return err | |||
} | |||
if _, err = sess.In("spec_id", deleteSpcIds).Delete(&ResourceSceneSpec{}); err != nil { | |||
return err | |||
} | |||
} | |||
} | |||
//update exists specs | |||
if len(updateList) > 0 { | |||
for _, v := range updateList { | |||
if _, err = sess.ID(v.ID).Update(&v); err != nil { | |||
return err | |||
} | |||
} | |||
} | |||
//insert new specs | |||
if len(insertList) > 0 { | |||
if _, err = sess.Insert(insertList); err != nil { | |||
return err | |||
} | |||
} | |||
return sess.Commit() | |||
} | |||
func GetResourceAiCenters() ([]ResourceAiCenterRes, error) { | |||
r := make([]ResourceAiCenterRes, 0) | |||
err := x.SQL("SELECT t.ai_center_code, t.ai_center_name FROM (SELECT DISTINCT ai_center_code, ai_center_name,cluster FROM resource_queue WHERE (deleted_time IS NULL OR deleted_time=0)) t ORDER BY cluster desc,ai_center_code asc").Find(&r) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return r, nil | |||
} |
@@ -0,0 +1,329 @@ | |||
package models | |||
import ( | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"errors" | |||
"xorm.io/builder" | |||
) | |||
const ( | |||
Exclusive = iota + 1 | |||
NotExclusive | |||
) | |||
type ResourceScene struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
SceneName string | |||
JobType string | |||
IsExclusive bool | |||
ExclusiveOrg string | |||
CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
CreatedBy int64 | |||
UpdatedTime timeutil.TimeStamp `xorm:"updated"` | |||
UpdatedBy int64 | |||
DeleteTime timeutil.TimeStamp `xorm:"deleted"` | |||
DeletedBy int64 | |||
} | |||
type ResourceSceneSpec struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
SceneId int64 `xorm:"unique(idx_scene_spec)"` | |||
SpecId int64 `xorm:"unique(idx_scene_spec)"` | |||
CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
} | |||
type ResourceSceneReq struct { | |||
ID int64 | |||
SceneName string | |||
JobType string | |||
IsExclusive bool | |||
ExclusiveOrg string | |||
CreatorId int64 | |||
SpecIds []int64 | |||
} | |||
type SearchResourceSceneOptions struct { | |||
ListOptions | |||
JobType string | |||
IsExclusive int | |||
AiCenterCode string | |||
QueueId int64 | |||
} | |||
type ResourceSceneListRes struct { | |||
TotalSize int64 | |||
List []ResourceSceneRes | |||
} | |||
func NewResourceSceneListRes(totalSize int64, list []ResourceSceneRes) *ResourceSceneListRes { | |||
return &ResourceSceneListRes{ | |||
TotalSize: totalSize, | |||
List: list, | |||
} | |||
} | |||
type ResourceSceneRes struct { | |||
ID int64 | |||
SceneName string | |||
JobType JobType | |||
IsExclusive bool | |||
ExclusiveOrg string | |||
Specs []ResourceSpecWithSceneId | |||
} | |||
func (ResourceSceneRes) TableName() string { | |||
return "resource_scene" | |||
} | |||
type ResourceSceneBriefRes struct { | |||
ID int64 | |||
SceneName string | |||
} | |||
func (ResourceSceneBriefRes) TableName() string { | |||
return "resource_scene" | |||
} | |||
type ResourceSpecWithSceneId struct { | |||
ID int64 | |||
SourceSpecId string | |||
AccCardsNum int | |||
CpuCores int | |||
MemGiB float32 | |||
GPUMemGiB float32 | |||
ShareMemGiB float32 | |||
UnitPrice int | |||
Status int | |||
UpdatedTime timeutil.TimeStamp | |||
SceneId int64 | |||
//queue | |||
Cluster string | |||
AiCenterCode string | |||
AiCenterName string | |||
QueueCode string | |||
QueueId int64 | |||
ComputeResource string | |||
AccCardType string | |||
} | |||
func (ResourceSpecWithSceneId) TableName() string { | |||
return "resource_specification" | |||
} | |||
func InsertResourceScene(r ResourceSceneReq) error { | |||
sess := x.NewSession() | |||
defer sess.Close() | |||
//check | |||
specs := make([]ResourceSpecification, 0) | |||
cond := builder.In("id", r.SpecIds).And(builder.Eq{"status": SpecOnShelf}) | |||
if err := sess.Where(cond).Find(&specs); err != nil { | |||
return err | |||
} | |||
if len(specs) < len(r.SpecIds) { | |||
return errors.New("specIds not correct") | |||
} | |||
rs := ResourceScene{ | |||
SceneName: r.SceneName, | |||
JobType: r.JobType, | |||
IsExclusive: r.IsExclusive, | |||
ExclusiveOrg: r.ExclusiveOrg, | |||
CreatedBy: r.CreatorId, | |||
UpdatedBy: r.CreatorId, | |||
} | |||
_, err := sess.InsertOne(&rs) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
if len(r.SpecIds) == 0 { | |||
return sess.Commit() | |||
} | |||
rss := make([]ResourceSceneSpec, len(r.SpecIds)) | |||
for i, v := range r.SpecIds { | |||
rss[i] = ResourceSceneSpec{ | |||
SceneId: rs.ID, | |||
SpecId: v, | |||
} | |||
} | |||
_, err = sess.Insert(&rss) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
return sess.Commit() | |||
} | |||
func UpdateResourceScene(r ResourceSceneReq) error { | |||
sess := x.NewSession() | |||
var err error | |||
defer func() { | |||
if err != nil { | |||
sess.Rollback() | |||
} | |||
sess.Close() | |||
}() | |||
// find old scene | |||
old := ResourceScene{} | |||
if has, _ := sess.ID(r.ID).Get(&old); !has { | |||
return errors.New("ResourceScene not exist") | |||
} | |||
//check specification | |||
specs := make([]ResourceSpecification, 0) | |||
cond := builder.In("id", r.SpecIds).And(builder.Eq{"status": SpecOnShelf}) | |||
if err := sess.Where(cond).Find(&specs); err != nil { | |||
return err | |||
} | |||
if len(specs) < len(r.SpecIds) { | |||
return errors.New("specIds not correct") | |||
} | |||
//update scene | |||
rs := ResourceScene{ | |||
SceneName: r.SceneName, | |||
IsExclusive: r.IsExclusive, | |||
ExclusiveOrg: r.ExclusiveOrg, | |||
} | |||
if _, err = sess.ID(r.ID).UseBool("is_exclusive").Update(&rs); err != nil { | |||
return err | |||
} | |||
//delete scene spec relation | |||
if _, err = sess.Where("scene_id = ? ", r.ID).Delete(&ResourceSceneSpec{}); err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
if len(r.SpecIds) == 0 { | |||
return sess.Commit() | |||
} | |||
//build new scene spec relation | |||
rss := make([]ResourceSceneSpec, len(r.SpecIds)) | |||
for i, v := range r.SpecIds { | |||
rss[i] = ResourceSceneSpec{ | |||
SceneId: r.ID, | |||
SpecId: v, | |||
} | |||
} | |||
if _, err = sess.Insert(&rss); err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
return sess.Commit() | |||
} | |||
func DeleteResourceScene(sceneId int64) error { | |||
sess := x.NewSession() | |||
var err error | |||
defer func() { | |||
if err != nil { | |||
sess.Rollback() | |||
} | |||
sess.Close() | |||
}() | |||
if _, err = sess.ID(sceneId).Delete(&ResourceScene{}); err != nil { | |||
return err | |||
} | |||
if _, err = sess.Where("scene_id = ? ", sceneId).Delete(&ResourceSceneSpec{}); err != nil { | |||
return err | |||
} | |||
return sess.Commit() | |||
} | |||
func SearchResourceScene(opts SearchResourceSceneOptions) (int64, []ResourceSceneRes, error) { | |||
var cond = builder.NewCond() | |||
if opts.Page <= 0 { | |||
opts.Page = 1 | |||
} | |||
if opts.JobType != "" { | |||
cond = cond.And(builder.Eq{"resource_scene.job_type": opts.JobType}) | |||
} | |||
if opts.IsExclusive == Exclusive { | |||
cond = cond.And(builder.Eq{"resource_scene.is_exclusive": 1}) | |||
} else if opts.IsExclusive == NotExclusive { | |||
cond = cond.And(builder.Eq{"resource_scene.is_exclusive": 0}) | |||
} | |||
if opts.AiCenterCode != "" { | |||
cond = cond.And(builder.Eq{"resource_queue.ai_center_code": opts.AiCenterCode}) | |||
} | |||
if opts.QueueId > 0 { | |||
cond = cond.And(builder.Eq{"resource_queue.id": opts.QueueId}) | |||
} | |||
cond = cond.And(builder.NewCond().Or(builder.Eq{"resource_scene.delete_time": 0}).Or(builder.IsNull{"resource_scene.delete_time"})) | |||
cols := []string{"resource_scene.id", "resource_scene.scene_name", "resource_scene.job_type", "resource_scene.is_exclusive", | |||
"resource_scene.exclusive_org"} | |||
count, err := x.Where(cond). | |||
Distinct("resource_scene.id"). | |||
Join("INNER", "resource_scene_spec", "resource_scene_spec.scene_id = resource_scene.id"). | |||
Join("INNER", "resource_specification", "resource_specification.id = resource_scene_spec.spec_id"). | |||
Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id"). | |||
Count(&ResourceSceneRes{}) | |||
if err != nil { | |||
return 0, nil, err | |||
} | |||
r := make([]ResourceSceneRes, 0) | |||
if err = x.Where(cond).Distinct(cols...). | |||
Join("INNER", "resource_scene_spec", "resource_scene_spec.scene_id = resource_scene.id"). | |||
Join("INNER", "resource_specification", "resource_specification.id = resource_scene_spec.spec_id"). | |||
Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id"). | |||
Desc("resource_scene.id"). | |||
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). | |||
Find(&r); err != nil { | |||
return 0, nil, err | |||
} | |||
if len(r) == 0 { | |||
return 0, r, err | |||
} | |||
//find related specs | |||
sceneIds := make([]int64, 0, len(r)) | |||
for _, v := range r { | |||
sceneIds = append(sceneIds, v.ID) | |||
} | |||
specs := make([]ResourceSpecWithSceneId, 0) | |||
if err := x.Cols("resource_specification.id", "resource_specification.source_spec_id", | |||
"resource_specification.acc_cards_num", "resource_specification.cpu_cores", | |||
"resource_specification.mem_gi_b", "resource_specification.gpu_mem_gi_b", | |||
"resource_specification.share_mem_gi_b", "resource_specification.unit_price", | |||
"resource_specification.status", "resource_specification.updated_time", | |||
"resource_scene_spec.scene_id", "resource_queue.cluster", | |||
"resource_queue.ai_center_code", "resource_queue.acc_card_type", | |||
"resource_queue.id as queue_id", "resource_queue.compute_resource", | |||
"resource_queue.queue_code", "resource_queue.ai_center_name", | |||
).In("resource_scene_spec.scene_id", sceneIds). | |||
Join("INNER", "resource_scene_spec", "resource_scene_spec.spec_id = resource_specification.id"). | |||
Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | |||
OrderBy("resource_specification.acc_cards_num"). | |||
Find(&specs); err != nil { | |||
return 0, nil, err | |||
} | |||
specsMap := make(map[int64][]ResourceSpecWithSceneId, 0) | |||
for _, v := range specs { | |||
if _, ok := specsMap[v.SceneId]; !ok { | |||
specsMap[v.SceneId] = []ResourceSpecWithSceneId{v} | |||
} else { | |||
specsMap[v.SceneId] = append(specsMap[v.SceneId], v) | |||
} | |||
} | |||
for i, v := range r { | |||
s := specsMap[v.ID] | |||
if s == nil { | |||
s = make([]ResourceSpecWithSceneId, 0) | |||
} | |||
r[i].Specs = s | |||
} | |||
return count, r, nil | |||
} |
@@ -0,0 +1,285 @@ | |||
package models | |||
import ( | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"xorm.io/builder" | |||
) | |||
const ( | |||
SpecNotVerified int = iota + 1 | |||
SpecOnShelf | |||
SpecOffShelf | |||
) | |||
type ResourceSpecification struct { | |||
ID int64 `xorm:"pk autoincr"` | |||
QueueId int64 `xorm:"INDEX"` | |||
SourceSpecId string `xorm:"INDEX"` | |||
AccCardsNum int | |||
CpuCores int | |||
MemGiB float32 | |||
GPUMemGiB float32 | |||
ShareMemGiB float32 | |||
UnitPrice int | |||
Status int | |||
IsAutomaticSync bool | |||
CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
CreatedBy int64 | |||
UpdatedTime timeutil.TimeStamp `xorm:"updated"` | |||
UpdatedBy int64 | |||
} | |||
func (r ResourceSpecification) ConvertToRes() *ResourceSpecificationRes { | |||
return &ResourceSpecificationRes{ | |||
ID: r.ID, | |||
SourceSpecId: r.SourceSpecId, | |||
AccCardsNum: r.AccCardsNum, | |||
CpuCores: r.CpuCores, | |||
MemGiB: r.MemGiB, | |||
ShareMemGiB: r.ShareMemGiB, | |||
GPUMemGiB: r.GPUMemGiB, | |||
UnitPrice: r.UnitPrice, | |||
Status: r.Status, | |||
UpdatedTime: r.UpdatedTime, | |||
} | |||
} | |||
type ResourceSpecificationReq struct { | |||
QueueId int64 `binding:"Required"` | |||
SourceSpecId string | |||
AccCardsNum int | |||
CpuCores int | |||
MemGiB float32 | |||
GPUMemGiB float32 | |||
ShareMemGiB float32 | |||
UnitPrice int | |||
Status int | |||
IsAutomaticSync bool | |||
CreatorId int64 | |||
} | |||
func (r ResourceSpecificationReq) ToDTO() ResourceSpecification { | |||
return ResourceSpecification{ | |||
QueueId: r.QueueId, | |||
SourceSpecId: r.SourceSpecId, | |||
AccCardsNum: r.AccCardsNum, | |||
CpuCores: r.CpuCores, | |||
MemGiB: r.MemGiB, | |||
GPUMemGiB: r.GPUMemGiB, | |||
ShareMemGiB: r.ShareMemGiB, | |||
UnitPrice: r.UnitPrice, | |||
Status: r.Status, | |||
IsAutomaticSync: r.IsAutomaticSync, | |||
CreatedBy: r.CreatorId, | |||
UpdatedBy: r.CreatorId, | |||
} | |||
} | |||
type SearchResourceSpecificationOptions struct { | |||
ListOptions | |||
QueueId int64 | |||
Status int | |||
Cluster string | |||
} | |||
type SearchResourceBriefSpecificationOptions struct { | |||
QueueId int64 | |||
Cluster string | |||
} | |||
type ResourceSpecAndQueueListRes struct { | |||
TotalSize int64 | |||
List []*ResourceSpecAndQueueRes | |||
} | |||
func NewResourceSpecAndQueueListRes(totalSize int64, list []ResourceSpecAndQueue) *ResourceSpecAndQueueListRes { | |||
resList := make([]*ResourceSpecAndQueueRes, len(list)) | |||
for i, v := range list { | |||
resList[i] = v.ConvertToRes() | |||
} | |||
return &ResourceSpecAndQueueListRes{ | |||
TotalSize: totalSize, | |||
List: resList, | |||
} | |||
} | |||
type ResourceSpecificationRes struct { | |||
ID int64 | |||
SourceSpecId string | |||
AccCardsNum int | |||
CpuCores int | |||
MemGiB float32 | |||
GPUMemGiB float32 | |||
ShareMemGiB float32 | |||
UnitPrice int | |||
Status int | |||
UpdatedTime timeutil.TimeStamp | |||
} | |||
func (ResourceSpecificationRes) TableName() string { | |||
return "resource_specification" | |||
} | |||
type ResourceSpecAndQueueRes struct { | |||
Spec *ResourceSpecificationRes | |||
Queue *ResourceQueueRes | |||
} | |||
type ResourceSpecAndQueue struct { | |||
ResourceSpecification `xorm:"extends"` | |||
ResourceQueue `xorm:"extends"` | |||
} | |||
func (*ResourceSpecAndQueue) TableName() string { | |||
return "resource_specification" | |||
} | |||
func (r ResourceSpecAndQueue) ConvertToRes() *ResourceSpecAndQueueRes { | |||
return &ResourceSpecAndQueueRes{ | |||
Spec: r.ResourceSpecification.ConvertToRes(), | |||
Queue: r.ResourceQueue.ConvertToRes(), | |||
} | |||
} | |||
func InsertResourceSpecification(r ResourceSpecification) (int64, error) { | |||
return x.Insert(&r) | |||
} | |||
func UpdateResourceSpecificationById(queueId int64, spec ResourceSpecification) (int64, error) { | |||
return x.ID(queueId).Update(&spec) | |||
} | |||
func UpdateSpecUnitPriceById(id int64, unitPrice int) error { | |||
_, err := x.Exec("update resource_specification set unit_price = ? ,updated_time = ? where id = ?", unitPrice, timeutil.TimeStampNow(), id) | |||
return err | |||
} | |||
func SearchResourceSpecification(opts SearchResourceSpecificationOptions) (int64, []ResourceSpecAndQueue, error) { | |||
var cond = builder.NewCond() | |||
if opts.Page <= 0 { | |||
opts.Page = 1 | |||
} | |||
if opts.QueueId > 0 { | |||
cond = cond.And(builder.Eq{"resource_specification.queue_id": opts.QueueId}) | |||
} | |||
if opts.Status > 0 { | |||
cond = cond.And(builder.Eq{"resource_specification.status": opts.Status}) | |||
} | |||
if opts.Cluster != "" { | |||
cond = cond.And(builder.Eq{"resource_queue.cluster": opts.Cluster}) | |||
} | |||
//cond = cond.And(builder.Or(builder.Eq{"resource_queue.deleted_time": 0}).Or(builder.IsNull{"resource_queue.deleted_time"})) | |||
n, err := x.Where(cond).Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | |||
Unscoped().Count(&ResourceSpecAndQueue{}) | |||
if err != nil { | |||
return 0, nil, err | |||
} | |||
r := make([]ResourceSpecAndQueue, 0) | |||
err = x.Where(cond). | |||
Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | |||
Desc("resource_specification.id"). | |||
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). | |||
Unscoped().Find(&r) | |||
if err != nil { | |||
return 0, nil, err | |||
} | |||
return n, r, nil | |||
} | |||
func GetSpecScenes(specId int64) ([]ResourceSceneBriefRes, error) { | |||
r := make([]ResourceSceneBriefRes, 0) | |||
err := x.Where("resource_scene_spec.spec_id = ?", specId). | |||
Join("INNER", "resource_scene_spec", "resource_scene_spec.scene_id = resource_scene.id"). | |||
Find(&r) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return r, nil | |||
} | |||
func ResourceSpecOnShelf(id int64, unitPrice int) error { | |||
_, err := x.Exec("update resource_specification set unit_price = ?,updated_time = ?,status = ? where id = ?", unitPrice, timeutil.TimeStampNow(), SpecOnShelf, id) | |||
return err | |||
} | |||
func ResourceSpecOffShelf(id int64) (int64, error) { | |||
sess := x.NewSession() | |||
var err error | |||
defer func() { | |||
if err != nil { | |||
sess.Rollback() | |||
} | |||
sess.Close() | |||
}() | |||
//delete scene spec relation | |||
if _, err = sess.Where("spec_id = ?", id).Delete(&ResourceSceneSpec{}); err != nil { | |||
return 0, err | |||
} | |||
param := ResourceSpecification{ | |||
Status: SpecOffShelf, | |||
} | |||
n, err := sess.Where("id = ? and status = ?", id, SpecOnShelf).Update(¶m) | |||
if err != nil { | |||
return 0, err | |||
} | |||
sess.Commit() | |||
return n, err | |||
} | |||
func GetResourceSpecification(r *ResourceSpecification) (*ResourceSpecification, error) { | |||
has, err := x.Get(r) | |||
if err != nil { | |||
return nil, err | |||
} else if !has { | |||
return nil, nil | |||
} | |||
return r, nil | |||
} | |||
func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceSpecification, existIds []int64) error { | |||
sess := x.NewSession() | |||
var err error | |||
defer func() { | |||
if err != nil { | |||
sess.Rollback() | |||
} | |||
sess.Close() | |||
}() | |||
//delete specs and scene that no longer exists | |||
deleteIds := make([]int64, 0) | |||
cond := builder.NewCond() | |||
cond = cond.And(builder.NotIn("resource_specification.id", existIds)).And(builder.Eq{"resource_queue.cluster": C2NetCluster}) | |||
if err := sess.Cols("resource_specification.id").Table("resource_specification"). | |||
Where(cond).Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id"). | |||
Find(&deleteIds); err != nil { | |||
return err | |||
} | |||
if len(deleteIds) > 0 { | |||
if _, err = sess.In("id", deleteIds).Update(&ResourceSpecification{Status: SpecOffShelf}); err != nil { | |||
return err | |||
} | |||
if _, err = sess.In("spec_id", deleteIds).Delete(&ResourceSceneSpec{}); err != nil { | |||
return err | |||
} | |||
} | |||
//update exists specs | |||
if len(updateList) > 0 { | |||
for _, v := range updateList { | |||
if _, err = sess.ID(v.ID).Update(&v); err != nil { | |||
return err | |||
} | |||
} | |||
} | |||
//insert new specs | |||
if len(insertList) > 0 { | |||
if _, err = sess.Insert(insertList); err != nil { | |||
return err | |||
} | |||
} | |||
return sess.Commit() | |||
} |
@@ -44,3 +44,11 @@ type EditAttachmentForm struct { | |||
func (f *EditAttachmentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
return validate(errs, ctx.Data, f, ctx.Locale) | |||
} | |||
type ReferenceDatasetForm struct { | |||
DatasetID []int64 `binding:"Required"` | |||
} | |||
func (f *ReferenceDatasetForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
return validate(errs, ctx.Data, f, ctx.Locale) | |||
} |
@@ -77,7 +77,10 @@ func (CloudbrainStopMsg) ShouldSend(ctx *TemplateContext) bool { | |||
} | |||
for _, v := range setting.CloudbrainStoppedNotifyList { | |||
if v == ctx.Cloudbrain.JobType { | |||
return true | |||
if ctx.Cloudbrain.Duration > 0 && ctx.Cloudbrain.EndTime > 0 { | |||
return true | |||
} | |||
break | |||
} | |||
} | |||
return false | |||
@@ -82,7 +82,7 @@ type GenerateCloudBrainTaskReq struct { | |||
} | |||
func GetCloudbrainDebugCommand() string { | |||
var command = `pip3 install jupyterlab==3 -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --ServerApp.shutdown_no_activity_timeout=` + setting.CullIdleTimeout + ` --TerminalManager.cull_inactive_timeout=` + setting.CullIdleTimeout + ` --TerminalManager.cull_interval=` + setting.CullInterval + ` --MappingKernelManager.cull_idle_timeout=` + setting.CullIdleTimeout + ` --MappingKernelManager.cull_interval=` + setting.CullInterval + ` --MappingKernelManager.cull_connected=True --MappingKernelManager.cull_busy=True --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --ServerApp.token="" --ServerApp.allow_origin="self https://cloudbrain.pcl.ac.cn" ` | |||
var command = `pip3 install jupyterlab==3 -i https://pypi.tuna.tsinghua.edu.cn/simple;pip3 install -U "nbclassic>=0.2.8" -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --ServerApp.shutdown_no_activity_timeout=` + setting.CullIdleTimeout + ` --TerminalManager.cull_inactive_timeout=` + setting.CullIdleTimeout + ` --TerminalManager.cull_interval=` + setting.CullInterval + ` --MappingKernelManager.cull_idle_timeout=` + setting.CullIdleTimeout + ` --MappingKernelManager.cull_interval=` + setting.CullInterval + ` --MappingKernelManager.cull_connected=True --MappingKernelManager.cull_busy=True --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --ServerApp.token="" --LabApp.token="" --ServerApp.allow_origin="self https://cloudbrain.pcl.ac.cn" ` | |||
return command | |||
} | |||
@@ -24,10 +24,11 @@ var ( | |||
) | |||
const ( | |||
JobHasBeenStopped = "S410" | |||
Public = "public" | |||
Custom = "custom" | |||
LogPageSize = 500 | |||
JobHasBeenStopped = "S410" | |||
errInvalidToken = "S401" | |||
Public = "public" | |||
Custom = "custom" | |||
LogPageSize = 500 | |||
LogPageTokenExpired = "5m" | |||
pageSize = 15 | |||
QueuesDetailUrl = "/rest-server/api/v2/queuesdetail" | |||
@@ -59,7 +60,7 @@ func loginCloudbrain() error { | |||
res, err := client.R(). | |||
SetHeader("Content-Type", "application/json"). | |||
SetBody(map[string]interface{}{"username": username, "password": password, "expiration": "604800"}). | |||
SetBody(map[string]interface{}{"username": username, "password": password, "expiration": conf.Expiration}). | |||
SetResult(&loginResult). | |||
Post(HOST + "/rest-server/api/v1/token") | |||
if err != nil { | |||
@@ -80,7 +81,8 @@ func GetQueuesDetail() (*map[string]int, error) { | |||
var jobResult models.QueueDetailResult | |||
var result = make(map[string]int, 0) | |||
retry := 0 | |||
sendjob: | |||
res, err := client.R(). | |||
SetHeader("Content-Type", "application/json"). | |||
SetAuthToken(TOKEN). | |||
@@ -91,6 +93,12 @@ func GetQueuesDetail() (*map[string]int, error) { | |||
return nil, fmt.Errorf("resty get queues detail failed: %s", err) | |||
} | |||
if (res.StatusCode() == http.StatusUnauthorized || jobResult.Code == errInvalidToken) && retry < 1 { | |||
retry++ | |||
_ = loginCloudbrain() | |||
goto sendjob | |||
} | |||
if jobResult.Code != Success { | |||
return nil, fmt.Errorf("jobResult err: %s", res.String()) | |||
} | |||
@@ -122,16 +130,12 @@ sendjob: | |||
Post(HOST + "/rest-server/api/v1/jobs/") | |||
if err != nil { | |||
if res != nil { | |||
var response models.CloudBrainResult | |||
json.Unmarshal(res.Body(), &response) | |||
log.Error("code(%s), msg(%s)", response.Code, response.Msg) | |||
return nil, fmt.Errorf(response.Msg) | |||
} | |||
return nil, fmt.Errorf("resty create job: %s", err) | |||
} | |||
if jobResult.Code == "S401" && retry < 1 { | |||
var response models.CloudBrainResult | |||
json.Unmarshal(res.Body(), &response) | |||
if response.Code == errInvalidToken && retry < 1 { | |||
retry++ | |||
_ = loginCloudbrain() | |||
goto sendjob | |||
@@ -163,7 +167,9 @@ sendjob: | |||
return nil, fmt.Errorf("resty GetJob: %v", err) | |||
} | |||
if getJobResult.Code == "S401" && retry < 1 { | |||
var response models.CloudBrainResult | |||
json.Unmarshal(res.Body(), &response) | |||
if response.Code == errInvalidToken && retry < 1 { | |||
retry++ | |||
_ = loginCloudbrain() | |||
goto sendjob | |||
@@ -196,13 +202,8 @@ sendjob: | |||
} | |||
var response models.CloudBrainResult | |||
err = json.Unmarshal(res.Body(), &response) | |||
if err != nil { | |||
log.Error("json.Unmarshal failed: %s", err.Error()) | |||
return &getImagesResult, fmt.Errorf("json.Unmarshal failed: %s", err.Error()) | |||
} | |||
if response.Code == "S401" && retry < 1 { | |||
json.Unmarshal(res.Body(), &response) | |||
if response.Code == errInvalidToken && retry < 1 { | |||
retry++ | |||
_ = loginCloudbrain() | |||
goto sendjob | |||
@@ -290,7 +291,9 @@ sendjob: | |||
return fmt.Errorf("resty CommitImage: %v", err) | |||
} | |||
if result.Code == "S401" && retry < 1 { | |||
var response models.CloudBrainResult | |||
json.Unmarshal(res.Body(), &response) | |||
if response.Code == errInvalidToken && retry < 1 { | |||
retry++ | |||
_ = loginCloudbrain() | |||
goto sendjob | |||
@@ -312,6 +315,7 @@ sendjob: | |||
} | |||
err = models.WithTx(func(ctx models.DBContext) error { | |||
models.UpdateAutoIncrementIndex() | |||
if dbImage != nil { | |||
dbImage.IsPrivate = params.IsPrivate | |||
dbImage.Description = params.ImageDescription | |||
@@ -441,7 +445,9 @@ sendjob: | |||
return fmt.Errorf("resty StopJob: %v", err) | |||
} | |||
if result.Code == "S401" && retry < 1 { | |||
var response models.CloudBrainResult | |||
json.Unmarshal(res.Body(), &response) | |||
if response.Code == errInvalidToken && retry < 1 { | |||
retry++ | |||
_ = loginCloudbrain() | |||
goto sendjob | |||
@@ -497,7 +503,7 @@ func GetJobAllLog(scrollID string) (*models.GetJobLogResult, error) { | |||
client := getRestyClient() | |||
var result models.GetJobLogResult | |||
req := models.GetAllJobLogParams{ | |||
Scroll: LogPageTokenExpired, | |||
Scroll: LogPageTokenExpired, | |||
ScrollID: scrollID, | |||
} | |||
@@ -521,7 +527,7 @@ func GetJobAllLog(scrollID string) (*models.GetJobLogResult, error) { | |||
return &result, nil | |||
} | |||
func DeleteJobLogToken(scrollID string) (error) { | |||
func DeleteJobLogToken(scrollID string) error { | |||
checkSetting() | |||
client := getRestyClient() | |||
var result models.DeleteJobLogTokenResult | |||
@@ -0,0 +1,43 @@ | |||
package context | |||
import ( | |||
"net/http" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/log" | |||
"gitea.com/macaron/macaron" | |||
) | |||
func RequireRepoReaderJson(unitType models.UnitType) macaron.Handler { | |||
return func(ctx *Context) { | |||
if !ctx.Repo.CanRead(unitType) { | |||
if log.IsTrace() { | |||
if ctx.IsSigned { | |||
log.Trace("Permission Denied: User %-v cannot read %-v in Repo %-v\n"+ | |||
"User in Repo has Permissions: %-+v", | |||
ctx.User, | |||
unitType, | |||
ctx.Repo.Repository, | |||
ctx.Repo.Permission) | |||
} else { | |||
log.Trace("Permission Denied: Anonymous user cannot read %-v in Repo %-v\n"+ | |||
"Anonymous user in Repo has Permissions: %-+v", | |||
unitType, | |||
ctx.Repo.Repository, | |||
ctx.Repo.Permission) | |||
} | |||
} | |||
ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("error.no_right"))) | |||
return | |||
} | |||
} | |||
} | |||
func RequireRepoWriterJson(unitType models.UnitType) macaron.Handler { | |||
return func(ctx *Context) { | |||
if !ctx.Repo.CanWrite(unitType) { | |||
ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("error.no_right"))) | |||
return | |||
} | |||
} | |||
} |
@@ -5,6 +5,7 @@ | |||
package cron | |||
import ( | |||
"code.gitea.io/gitea/services/cloudbrain/resource" | |||
"code.gitea.io/gitea/modules/modelarts" | |||
"context" | |||
"time" | |||
@@ -208,6 +209,17 @@ func registerSyncCloudbrainStatus() { | |||
}) | |||
} | |||
func registerSyncResourceSpecs() { | |||
RegisterTaskFatal("sync_grampus_specs", &BaseConfig{ | |||
Enabled: true, | |||
RunAtStart: true, | |||
Schedule: "0 0 1 * * ?", | |||
}, func(ctx context.Context, _ *models.User, _ Config) error { | |||
resource.SyncGrampusQueueAndSpecs() | |||
return nil | |||
}) | |||
} | |||
func registerSyncModelArtsTempJobs() { | |||
RegisterTaskFatal("sync_model_arts_temp_jobs", &BaseConfig{ | |||
Enabled: true, | |||
@@ -239,5 +251,6 @@ func initBasicTasks() { | |||
registerSyncCloudbrainStatus() | |||
registerHandleOrgStatistic() | |||
registerSyncResourceSpecs() | |||
registerSyncModelArtsTempJobs() | |||
} |
@@ -1,5 +1,7 @@ | |||
package dataset | |||
import "code.gitea.io/gitea/models" | |||
func GetResourceType(cloudbrainType int) string { | |||
if cloudbrainType == 0 { | |||
return "CPU/GPU" | |||
@@ -15,3 +17,19 @@ func GetStatusText(isPrivate bool) string { | |||
return "dataset.public" | |||
} | |||
} | |||
func IsShowDataSetOfCurrentRepo(repoID int64) bool { | |||
repo := models.Repository{ | |||
ID: repoID, | |||
} | |||
dataset, _ := models.GetDatasetByRepo(&repo) | |||
if dataset != nil { | |||
return true | |||
} | |||
if models.HasReferenceDataset(repoID) { | |||
return false | |||
} | |||
return true | |||
} |
@@ -23,9 +23,7 @@ const ( | |||
NpuWorkDir = "/cache/" | |||
CommandPrepareScript = ";mkdir -p output;mkdir -p code;mkdir -p dataset;echo \"start loading script\";wget -q https://git.openi.org.cn/OpenIOSSG/script_for_grampus/archive/master.zip;" + | |||
"echo \"finish loading script\";unzip -q master.zip;cd script_for_grampus;chmod 777 downloader_for_obs uploader_for_obs downloader_for_minio uploader_for_minio;" | |||
//CommandPrepareScript = "pwd;cd /cache;mkdir -p output;mkdir -p code;mkdir -p dataset;echo \"start loading script\";wget -q https://git.openi.org.cn/OpenIOSSG/script_for_grampus/archive/master.zip;" + | |||
// "echo \"finish loading script\";unzip -q master.zip;cd script_for_grampus;chmod 777 downloader_for_obs uploader_for_obs downloader_for_minio uploader_for_minio;" | |||
"echo \"finish loading script\";unzip -q master.zip;cd script_for_grampus;chmod 777 downloader_for_obs uploader_for_npu downloader_for_minio uploader_for_gpu;" | |||
CodeArchiveName = "master.zip" | |||
) | |||
@@ -23,6 +23,7 @@ const ( | |||
urlGetToken = urlOpenApiV1 + "token" | |||
urlTrainJob = urlOpenApiV1 + "trainjob" | |||
urlGetResourceSpecs = urlOpenApiV1 + "resourcespec" | |||
urlGetAiCenter = urlOpenApiV1 + "sharescreen/aicenter" | |||
urlGetImages = urlOpenApiV1 + "image" | |||
errorIllegalToken = 1005 | |||
@@ -275,3 +276,35 @@ sendjob: | |||
return &result, nil | |||
} | |||
func GetAiCenters(pageIndex, pageSize int) (*models.GetGrampusAiCentersResult, error) { | |||
checkSetting() | |||
client := getRestyClient() | |||
var result models.GetGrampusAiCentersResult | |||
retry := 0 | |||
sendjob: | |||
_, err := client.R(). | |||
SetAuthToken(TOKEN). | |||
SetResult(&result). | |||
Get(HOST + urlGetAiCenter + "?pageIndex=" + fmt.Sprint(pageIndex) + "&pageSize=" + fmt.Sprint(pageSize)) | |||
if err != nil { | |||
return nil, fmt.Errorf("resty GetAiCenters: %v", err) | |||
} | |||
if result.ErrorCode == errorIllegalToken && retry < 1 { | |||
retry++ | |||
log.Info("retry get token") | |||
_ = getToken() | |||
goto sendjob | |||
} | |||
if result.ErrorCode != 0 { | |||
log.Error("GetAiCenters failed(%d): %s", result.ErrorCode, result.ErrorMsg) | |||
return &result, fmt.Errorf("GetAiCenters failed(%d): %s", result.ErrorCode, result.ErrorMsg) | |||
} | |||
return &result, nil | |||
} |
@@ -134,6 +134,7 @@ type GenerateInferenceJobReq struct { | |||
ModelVersion string | |||
CkptName string | |||
ResultUrl string | |||
DatasetName string | |||
} | |||
type VersionInfo struct { | |||
@@ -690,11 +691,11 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
return err | |||
} | |||
attach, err := models.GetAttachmentByUUID(req.Uuid) | |||
if err != nil { | |||
log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | |||
return err | |||
} | |||
// attach, err := models.GetAttachmentByUUID(req.Uuid) | |||
// if err != nil { | |||
// log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | |||
// return err | |||
// } | |||
jobID := strconv.FormatInt(jobResult.JobID, 10) | |||
err = models.CreateCloudbrain(&models.Cloudbrain{ | |||
Status: TransTrainJobStatus(jobResult.Status), | |||
@@ -708,7 +709,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
VersionID: jobResult.VersionID, | |||
VersionName: jobResult.VersionName, | |||
Uuid: req.Uuid, | |||
DatasetName: attach.Name, | |||
DatasetName: req.DatasetName, | |||
CommitID: req.CommitID, | |||
EngineID: req.EngineID, | |||
TrainUrl: req.TrainUrl, | |||
@@ -5,6 +5,7 @@ type CloudbrainLoginConfig struct { | |||
Password string | |||
Host string | |||
ImageURLPrefix string | |||
Expiration string | |||
} | |||
var ( | |||
@@ -17,5 +18,6 @@ func GetCloudbrainConfig() CloudbrainLoginConfig { | |||
Cloudbrain.Password = cloudbrainSec.Key("PASSWORD").MustString("") | |||
Cloudbrain.Host = cloudbrainSec.Key("REST_SERVER_HOST").MustString("") | |||
Cloudbrain.ImageURLPrefix = cloudbrainSec.Key("IMAGE_URL_PREFIX").MustString("") | |||
Cloudbrain.Expiration = cloudbrainSec.Key("EXPIRATION").MustString("604800") | |||
return Cloudbrain | |||
} |
@@ -193,8 +193,9 @@ var ( | |||
Wiki: []string{"never"}, | |||
}, | |||
} | |||
RepoRootPath string | |||
ScriptType = "bash" | |||
RepoRootPath string | |||
RepoMaxReferenceDatasetNum int | |||
ScriptType = "bash" | |||
) | |||
func newRepository() { | |||
@@ -210,6 +211,8 @@ func newRepository() { | |||
Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool() | |||
Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1) | |||
RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gitea-repositories")) | |||
RepoMaxReferenceDatasetNum = sec.Key("MAX_REF_DATASET_NUM").MustInt(20) | |||
forcePathSeparator(RepoRootPath) | |||
if !filepath.IsAbs(RepoRootPath) { | |||
RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath) | |||
@@ -97,23 +97,24 @@ func NewFuncMap() []template.FuncMap { | |||
"AllowedReactions": func() []string { | |||
return setting.UI.Reactions | |||
}, | |||
"AvatarLink": models.AvatarLink, | |||
"Safe": Safe, | |||
"SafeJS": SafeJS, | |||
"Str2html": Str2html, | |||
"subOne": subOne, | |||
"TimeSince": timeutil.TimeSince, | |||
"TimeSinceUnix": timeutil.TimeSinceUnix, | |||
"TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||
"AttachmentResourceType": dataset.GetResourceType, | |||
"AttachmentStatus": dataset.GetStatusText, | |||
"TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||
"RawTimeSince": timeutil.RawTimeSince, | |||
"FileSize": base.FileSize, | |||
"PrettyNumber": base.PrettyNumber, | |||
"Subtract": base.Subtract, | |||
"EntryIcon": base.EntryIcon, | |||
"MigrationIcon": MigrationIcon, | |||
"AvatarLink": models.AvatarLink, | |||
"Safe": Safe, | |||
"SafeJS": SafeJS, | |||
"Str2html": Str2html, | |||
"subOne": subOne, | |||
"TimeSince": timeutil.TimeSince, | |||
"TimeSinceUnix": timeutil.TimeSinceUnix, | |||
"TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||
"AttachmentResourceType": dataset.GetResourceType, | |||
"AttachmentStatus": dataset.GetStatusText, | |||
"IsShowDataSetOfCurrentRepo": dataset.IsShowDataSetOfCurrentRepo, | |||
"TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||
"RawTimeSince": timeutil.RawTimeSince, | |||
"FileSize": base.FileSize, | |||
"PrettyNumber": base.PrettyNumber, | |||
"Subtract": base.Subtract, | |||
"EntryIcon": base.EntryIcon, | |||
"MigrationIcon": MigrationIcon, | |||
"Add": func(a, b int) int { | |||
return a + b | |||
}, | |||
@@ -357,13 +358,15 @@ func NewTextFuncMap() []texttmpl.FuncMap { | |||
"AppDomain": func() string { | |||
return setting.Domain | |||
}, | |||
"TimeSince": timeutil.TimeSince, | |||
"TimeSinceUnix": timeutil.TimeSinceUnix, | |||
"TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||
"TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||
"RawTimeSince": timeutil.RawTimeSince, | |||
"AttachmentResourceType": dataset.GetResourceType, | |||
"AttachmentStatus": dataset.GetStatusText, | |||
"TimeSince": timeutil.TimeSince, | |||
"TimeSinceUnix": timeutil.TimeSinceUnix, | |||
"TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||
"TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||
"RawTimeSince": timeutil.RawTimeSince, | |||
"AttachmentResourceType": dataset.GetResourceType, | |||
"AttachmentStatus": dataset.GetStatusText, | |||
"IsShowDataSetOfCurrentRepo": dataset.IsShowDataSetOfCurrentRepo, | |||
"DateFmtLong": func(t time.Time) string { | |||
return t.Format(time.RFC1123Z) | |||
}, | |||
@@ -98,6 +98,7 @@ error500= Sorry, the site has encountered some problems, we are trying to <stron | |||
[error] | |||
occurred = An error has occurred | |||
report_message = An error has occurred | |||
no_right=You have no right to do the operation. | |||
[install] | |||
install = Installation | |||
@@ -253,13 +254,15 @@ page_dev_env_desc2_desc=Associate the model with the code version, you can adjus | |||
page_dev_env_desc3_title=Once Configuration, Multiple Reuse | |||
page_dev_env_desc3_desc=Provide execution environment sharing, Once Configuration, Multiple Reuse. Lower the threshold of model development, and avoid spending repetitive time configuring complex environments. | |||
page_dev_yunlao=OpenI AI Collaboration Platform | |||
page_dev_yunlao_desc1=OpenI AI collaboration platform has cooperated with Pengcheng cloud brain and China computing power network (c ² Net) can be used to complete AI development tasks by using the rich computing resources of Pengcheng cloud brain and China computing network. | |||
page_dev_yunlao_desc1=OpenI AI collaboration platform has cooperated with Pengcheng cloud brain and China computing power network (C²NET) can be used to complete AI development tasks by using the rich computing resources of Pengcheng cloud brain and China computing network. | |||
page_dev_yunlao_desc2=Pengcheng CloudBrain's existing AI computing power is 100p FLOPS@FP16 (billions of half precision floating-point calculations per second), the main hardware infrastructure consists of GPU servers equipped with NVIDIA Tesla V100 and A100, and Atlas 900 AI clusters equipped with Kunpeng and shengteng processors. | |||
page_dev_yunlao_desc3=China computing power network (c ² Net) phase I can realize high-speed network interconnection between different artificial intelligence computing centers, and realize reasonable scheduling of computing power and flexible allocation of resources. At present, 11 intelligent computing centers have been connected, and the total scale of computing power is 1924p OPS@FP16 。 Qizhi AI collaboration platform has been connected to Pengcheng Cloud Computing Institute, Chengdu Intelligent Computing Center, Zhongyuan Intelligent Computing Center, Hefei brain and other nodes. | |||
page_dev_yunlao_desc3=China computing power network (C²NET) phase I can realize high-speed network interconnection between different artificial intelligence computing centers, and realize reasonable scheduling of computing power and flexible allocation of resources. At present, 11 intelligent computing centers have been connected, and the total scale of computing power is 1924p OPS@FP16. OpenI AI collaboration platform has been connected to Pengcheng Cloud Computing Institute, Chengdu Intelligent Computing Center, Zhongyuan Intelligent Computing Center, Hefei brain and other nodes. | |||
page_dev_yunlao_desc4=Developers can freely select the corresponding computing resources according to the use needs, and can test the adaptability, performance, stability, etc. of the model in different hardware environments. | |||
page_dev_yunlao_desc5=If your model requires more computing resources, you can also apply for it separately. | |||
page_dev_yunlao_apply=Apply Separately | |||
c2net_title=China Computing Network | |||
c2net_desc=The artificial intelligence computing power network promotion alliance has access to 11 intelligent computing centers, with a total scale of 1924p. | |||
c2net_center=Center | |||
search=Search | |||
search_repo=Repository | |||
search_dataset=DataSet | |||
@@ -822,6 +825,9 @@ title_format_err=Name can only contain number,letter,'-','_' or '.', and can be | |||
description = Description | |||
description_format_err=Description's length can be up to %s characters long. | |||
create_dataset = Create Dataset | |||
download_url=Download Url | |||
download_oper=Operation | |||
download_copy=Copy URL | |||
create_dataset_fail=Failed to create dataset. | |||
query_dataset_fail=Failed to query dataset. | |||
edit_attachment_fail=Failed to update description. | |||
@@ -832,6 +838,8 @@ category = Category | |||
no_category = No Category | |||
task = Task | |||
no_task = No Task | |||
reference_dataset_fail=Failed to reference dataset, please try again later. | |||
cancel_reference_dataset_fail=Failed to cancel reference dataset, please try again later. | |||
license = License | |||
no_license = No License | |||
file = Dataset File | |||
@@ -915,9 +923,10 @@ select_task = Select Research Direction/Application Area | |||
dataset_name_tooltips = Please enter letters, numbers, _ and - up to 100 characters. | |||
dataset_no_create = No dataset has been created yet | |||
dataset_explain = Dataset: CloudBrain I provides CPU/GPU resources, Cloudbrain II provides Ascend NPU resources, and the data set used for debugging also needs to be uploaded to the corresponding environment; | |||
dataset_instructions_for_use = Instructions for use: You can refer to Qizhi AI Collaboration Platform | |||
dataset_camp_course = Newcomer Training Camp Course; | |||
dataset_instructions_for_use = Instructions for use: You can refer to Openi AI Collaboration Platform | |||
dataset_camp_course = OpenI_Learning; | |||
dataset_upload = Upload | |||
dataset_upload_status= Upload Status | |||
dataset_file_name = File Name | |||
dataset_available_clusters = Available Clusters | |||
dataset_upload_time = Upload Time | |||
@@ -944,6 +953,14 @@ unzip_failed=Unzip Failed | |||
unzip_stared=Unzipping | |||
unzip_status=Unzip Status | |||
collection_num=Collection Nums | |||
current_dataset=Current Dataset | |||
linked_dataset=Linked Dataset | |||
unfavorite=Unlike | |||
favorite=Like | |||
disassociate=Disassociate | |||
benchmark_dataset_tip=Note: first use the dataset function to upload the model, and then select the model from the dataset list. | |||
file_deleted=The file has been deleted | |||
[repo] | |||
owner = Owner | |||
repo_name = Repository Name | |||
@@ -1099,7 +1116,8 @@ modelarts.status=Status | |||
modelarts.createtime=CreateTime | |||
modelarts.version_nums = Version Nums | |||
modelarts.version = Version | |||
modelarts.computing_resources=compute Resources | |||
modelarts.computing_resources=Compute Resources | |||
modelarts.cluster.computing_resources=Cluster/Compute Resources | |||
modelarts.ai_center=Ai Center | |||
modelarts.card_type=Card Type | |||
modelarts.cluster=Cluster | |||
@@ -1123,7 +1141,7 @@ modelarts.train_job.compute_node=Compute Node | |||
modelarts.create_model = Create Model | |||
modelarts.model_label=Model Label | |||
modelarts.infer_dataset = Inference Dataset | |||
modelarts.train_job.label_place=Input labels, multiple labels are separated by spaces | |||
modelarts.train_job.basic_info=Basic Info | |||
modelarts.train_job.job_status=Job Status | |||
@@ -1192,7 +1210,7 @@ modelarts.infer_job_model_file = Model File | |||
modelarts.infer_job = Inference Job | |||
modelarts.infer_job.model_version = Model/Version | |||
modelarts.infer_job.select_model = Select Model | |||
modelarts.infer_job.boot_file_helper=The startup file is the entry file for your program execution and must end in.py.Such as inference.py, main.py, example/inference. Py, case/main.py. | |||
modelarts.infer_job.boot_file_helper=The startup file is the entry file for your program execution and must end in.py.Such as inference.py, main.py, example/inference.py, case/main.py. | |||
modelarts.infer_job.tooltip = The model has been deleted and cannot be viewed. | |||
modelarts.download_log=Download log file | |||
@@ -1204,7 +1222,10 @@ model_Evaluation_not_created = Model evaluation has not been created | |||
repo_not_initialized = Code version: You have not initialized the code repository, please <a href="%s"> initialized </a> first ; | |||
debug_task_running_limit =Running time: no more than 4 hours, it will automatically stop if it exceeds 4 hours; | |||
dataset_desc = Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU.And dataset also needs to be uploaded to the corresponding environment; | |||
platform_instructions = Instructions for use: You can refer to the <a href="https://git.openi.org.cn/zeizei/OpenI_Learning">Xiaobai training camp </a> course of Qizhi AI collaboration platform. | |||
platform_instructions = Instructions for use: You can refer to the <a href="https://git.openi.org.cn/zeizei/OpenI_Learning"> OpenI_Learning </a> course of Qizhi AI collaboration platform. | |||
platform_instructions1 = Instructions for use: You can refer to the | |||
platform_instructions2 = OpenI_Learning | |||
platform_instructions3 = course of Openi AI collaboration platform. | |||
model_not_exist = Model file: You do not have a model file yet, please generate and <a href="%s/modelmanage/show_model">export the model</a> through the <a href="%s/modelarts/train-job">training task</a> first ; | |||
benchmark_leaderboards = Benchmark leaderboards | |||
@@ -1215,7 +1236,7 @@ model.manage.version = Version | |||
model.manage.label = Label | |||
model.manage.size = Size | |||
model.manage.create_time = Create Time | |||
model.manage.Description = Description | |||
model.manage.description = Description | |||
model.manage.Accuracy = Accuracy | |||
model.manage.F1 = F1 | |||
model.manage.Precision = Precision | |||
@@ -1227,6 +1248,49 @@ model.convert=Model Transformation | |||
model.list=Model List | |||
model.manage.create_new_convert_task=Create Model Transformation Task | |||
model.manage.notcreatemodel=No model has been created | |||
model.manage.init1=Code version: You have not initialized the code repository, please | |||
model.manage.init2=initialized first ; | |||
model.manage.createtrainjob_tip=Training task: you haven't created a training task, please create it first | |||
model.manage.createtrainjob=Training task. | |||
model.manage.delete=Delete Model | |||
model.manage.delete_confirm=Are you sure to delete this model? Once this model is deleted, it cannot be restored. | |||
model.manage.select.trainjob=Select train task | |||
model.manage.select.version=Select version | |||
model.manage.engine=Model engine | |||
model.manage.select.engine=Select model engine | |||
model.manage.modelfile=Model file | |||
model.manage.modellabel=Model label | |||
model.manage.modeldesc=Model description | |||
model.manage.baseinfo=Base Information | |||
modelconvert.notcreate=No model conversion task has been created. | |||
modelconvert.importfirst1=Please import the | |||
modelconvert.importfirst2=model | |||
modelconvert.importfirst3=first, then converts it. | |||
modelconvert.download=Download | |||
modelconvert.taskname=Task name | |||
modelconvert.modelname=Model name | |||
modelconvert.selectmodel=Select model | |||
modelconvert.modelversion=Model version | |||
modelconvert.selectversion=Select version | |||
modelconvert.selectmodelfile=Select model file | |||
modelconvert.taskstatus=Status | |||
modelconvert.srcengine=Source model engine | |||
modelconvert.outputformat=Output format | |||
modelconvert.createtime=Created time | |||
modelconvert.inputdataformat=Input data format | |||
modelconvert.inputshape=Input tensor shape | |||
modelconvert.inputshapetip=For example: 1,1,32,32, corresponding to the input data format. | |||
modelconvert.netoutputdata=Network output data type | |||
modelconvert.taskdesc=Task description | |||
modelconvert.newtask=New | |||
modelconvert.createtask=Create model transformation task | |||
modelconvert.taskurlname=Model transformation task | |||
log_scroll_start=Scroll to top | |||
log_scroll_end=Scroll to bottom | |||
modelconvert.tasknameempty=Please enter a task name. | |||
modelconvert.inputshapeerror=Format input error, please input such as: 1,1,32,32, corresponding to the input data format. | |||
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 does not exist. | |||
@@ -2323,7 +2387,7 @@ topic.count_prompt = You can not select more than 25 topics | |||
topic.format_prompt = Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long. | |||
imagetopic.format_prompt = Topics can be up to 35 characters long. | |||
use_repo_agreement=I promise that the content of this warehouse does not violate any national laws and regulations. During the use of the warehouse, I will abide by the OpenI community management regulations and platform usage rules, and will not conduct malicious attacks, mining, or any other illegal or disruptive platform order. Information release and related behaviors. For more information please refer to | |||
openi_use_agreement=OpenI Qizhi Community Platform Use Agreement. | |||
openi_use_agreement=OpenI Openi Community Platform Use Agreement. | |||
[org] | |||
org_name_holder = Organization Name | |||
org_full_name_holder = Organization Full Name | |||
@@ -2964,6 +3028,13 @@ notices.desc = Description | |||
notices.op = Op. | |||
notices.delete_success = The system notices have been deleted. | |||
user_management = User Management | |||
resource_management = Resource Management | |||
resource_pool = Resource Pool(queue) | |||
resource_price = Resource Price | |||
application_scenario = Application Scenario | |||
system_configuration = System Configuration | |||
[action] | |||
create_repo = created repository <a href="%s">%s</a> | |||
rename_repo = renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a> | |||
@@ -2990,15 +3061,15 @@ mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href= | |||
approve_pull_request = `approved <a href="%s/pulls/%s">%s#%[2]s</a>` | |||
reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>` | |||
upload_dataset=`upload dataset <a href="%s/datasets">%s</a>` | |||
task_gpudebugjob=`created CPU/GPU type debugging task<a href="%s/cloudbrain/%s">%s</a>` | |||
task_gpudebugjob=`created CPU/GPU type debugging task <a href="%s/cloudbrain/%s">%s</a>` | |||
task_npudebugjob=`created NPU type debugging task <a href="%s/modelarts/notebook/%s">%s</a>` | |||
task_nputrainjob=`created NPU training task<a href="%s/modelarts/train-job/%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>` | |||
task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name=%s">%s</a>` | |||
task_gputrainjob=`created CPU/GPU training task<a href="%s/cloudbrain/train-job/%s">%s</a>` | |||
task_c2netnputrainjob=`created NPU training task<a href="%s/grampus/train-job/%s">%s</a>` | |||
task_c2netgputrainjob=`created CPU/GPU training task<a href="%s/grampus/train-job/%s">%s</a>` | |||
task_gputrainjob=`created CPU/GPU training task <a href="%s/cloudbrain/train-job/%s">%s</a>` | |||
task_c2netnputrainjob=`created NPU training task <a href="%s/grampus/train-job/%s">%s</a>` | |||
task_c2netgputrainjob=`created CPU/GPU training task <a href="%s/grampus/train-job/%s">%s</a>` | |||
[tool] | |||
ago = %s ago | |||
@@ -3092,6 +3163,8 @@ all_ai_center=All Computing NET | |||
resource_cluster = Resource Cluster | |||
resource_cluster_openi = OpenI Resource Cluster | |||
resource_cluster_c2net = China Computing NET | |||
resource_cluster_openi_simple = OpenI | |||
resource_cluster_c2net_simple = C²NET | |||
compute_resource = Computing resources | |||
task_name = Task name | |||
task_type = Task type | |||
@@ -3113,10 +3186,11 @@ specification = specification | |||
select_specification = select specification | |||
description = description | |||
wrong_specification=You cannot use this specification, please choose another item. | |||
resource_use=Resource Occupancy | |||
job_name_rule = Please enter letters, numbers, _ and - up to 64 characters and cannot end with a dash (-). | |||
dataset_path_rule = The dataset location is stored in the environment variable data_url, and the training output path is stored in the environment variable train_url. | |||
train_dataset_path_rule = The dataset location is stored in the environment variable <strong style="color:#010101">data_url</strong>, and the output path is stored in the environment variable <strong style="color:#010101">train_url</strong>. | |||
infer_dataset_path_rule = The dataset location is stored in the environment variable <strong style="color:#010101">data_url</strong>, and the output path is stored in the environment variable <strong style="color:#010101">result_url</strong>. | |||
view_sample = View sample | |||
inference_output_path_rule = The inference output path is stored in the environment variable result_url. | |||
model_file_path_rule=The model file location is stored in the environment variable ckpt_url | |||
@@ -3149,3 +3223,5 @@ Stopped_success_update_status_fail=Succeed in stopping th job, but failed to upd | |||
load_code_failed=Fail to load code, please check if the right branch is selected. | |||
error.dataset_select = dataset select error:the count exceed the limit or has same name | |||
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>, 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. |
@@ -99,6 +99,7 @@ error500=抱歉,站点遇到一些问题,我们正尝试<strong>修复网页 | |||
[error] | |||
occurred=发生错误 | |||
report_message=发生错误 | |||
no_right=您没有权限执行本操作。 | |||
[install] | |||
install=安装页面 | |||
@@ -261,7 +262,9 @@ page_dev_yunlao_desc3=中国算力网(C²NET)一期可实现不同人工智 | |||
page_dev_yunlao_desc4=开发者可以根据使用需求,自由选择相应计算资源,可以测试模型在不同硬件环境下的适配能力、性能、稳定性等。 | |||
page_dev_yunlao_desc5=如果您的模型需要更多的计算资源,也可以单独申请。 | |||
page_dev_yunlao_apply=单独申请 | |||
c2net_title=智算网络 | |||
c2net_desc=人工智能算力网络推进联盟已接入11家智算中心,算力总规模1924P | |||
c2net_center=中心 | |||
search=搜索 | |||
search_repo=项目 | |||
search_dataset=数据集 | |||
@@ -831,6 +834,12 @@ create_dataset_fail=创建数据集失败。 | |||
query_dataset_fail=查询数据集失败。 | |||
edit_attachment_fail=修改描述失败。 | |||
reference_dataset_fail=关联数据集失败,请稍后再试。 | |||
cancel_reference_dataset_fail=取消关联数据集失败,请稍后再试。 | |||
download_url=数据集下载地址 | |||
download_copy=复制链接 | |||
download_oper=操作 | |||
show_dataset=数据集 | |||
edit_dataset=编辑数据集 | |||
update_dataset=更新数据集 | |||
@@ -923,6 +932,7 @@ dataset_explain = 数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Asc | |||
dataset_instructions_for_use = 使用说明:可以参考启智AI协作平台 | |||
dataset_camp_course = 小白训练营课程 | |||
dataset_upload = 上传 | |||
dataset_upload_status = 上传状态 | |||
dataset_file_name = 文件名称 | |||
dataset_available_clusters = 可用集群 | |||
dataset_upload_time = 上传时间 | |||
@@ -949,6 +959,14 @@ unzip_failed=解压失败 | |||
unzip_stared=解压中 | |||
unzip_status=解压状态 | |||
collection_num=收藏数量 | |||
current_dataset=当前数据集 | |||
linked_dataset=关联数据集 | |||
unfavorite=取消收藏 | |||
favorite=收藏 | |||
disassociate=取消关联 | |||
benchmark_dataset_tip=说明:先使用数据集功能上传模型,然后从数据集列表选模型。 | |||
file_deleted=文件已经被删除 | |||
[repo] | |||
owner=拥有者 | |||
repo_name=项目名称 | |||
@@ -1110,6 +1128,7 @@ modelarts.deletetime=删除时间 | |||
modelarts.version_nums=版本数 | |||
modelarts.version=版本 | |||
modelarts.computing_resources=计算资源 | |||
modelarts.cluster.computing_resources=集群/计算资源 | |||
modelarts.ai_center=智算中心 | |||
modelarts.card_type=卡类型 | |||
modelarts.cluster=集群 | |||
@@ -1217,6 +1236,10 @@ repo_not_initialized = 代码版本:您还没有初始化代码仓库,请先 | |||
debug_task_running_limit = 运行时长:最长不超过4个小时,超过4个小时将自动停止; | |||
dataset_desc = 数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,调试使用的数据集也需要上传到对应的环境; | |||
platform_instructions = 使用说明:可以参考启智AI协作平台<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程</a>。 | |||
platform_instructions1 = 使用说明:可以参考启智AI协作平台 | |||
platform_instructions2 = 小白训练营课程 | |||
platform_instructions3 = 。 | |||
model_not_exist = 模型文件:您还没有模型文件,请先通过<a href="%s/modelarts/train-job">训练任务</a>产生并 <a href="%s/modelmanage/show_model">导出模型</a> ; | |||
benchmark_leaderboards = 基准测试排行榜 | |||
@@ -1239,6 +1262,50 @@ model.convert=模型转换任务 | |||
model.list=模型列表 | |||
model.manage.create_new_convert_task=创建模型转换任务 | |||
model.manage.notcreatemodel=未创建过模型 | |||
model.manage.init1=代码版本:您还没有初始化代码仓库,请先 | |||
model.manage.init2=创建代码版本; | |||
model.manage.createtrainjob_tip=训练任务:您还没创建过训练任务,请先创建 | |||
model.manage.createtrainjob=训练任务。 | |||
model.manage.delete=删除模型 | |||
model.manage.delete_confirm=你确认删除该模型么?此模型一旦删除不可恢复。 | |||
model.manage.select.trainjob=选择训练任务 | |||
model.manage.select.version=选择版本 | |||
model.manage.engine=模型框架 | |||
model.manage.select.engine=选择模型框架 | |||
model.manage.modelfile=模型文件 | |||
model.manage.modellabel=模型标签 | |||
model.manage.modeldesc=模型描述 | |||
model.manage.baseinfo=基本信息 | |||
modelconvert.notcreate=未创建过模型转换任务 | |||
modelconvert.importfirst1=请您先导入 | |||
modelconvert.importfirst2=模型 | |||
modelconvert.importfirst3=,然后再对其进行转换。 | |||
modelconvert.download=下载 | |||
modelconvert.taskname=任务名称 | |||
modelconvert.modelname=模型名称 | |||
modelconvert.selectmodel=选择模型 | |||
modelconvert.modelversion=模型版本 | |||
modelconvert.selectversion=选择版本 | |||
modelconvert.selectmodelfile=选择模型文件 | |||
modelconvert.taskstatus=状态 | |||
modelconvert.srcengine=原模型框架 | |||
modelconvert.outputformat=转换后格式 | |||
modelconvert.createtime=创建时间 | |||
modelconvert.inputdataformat=输入数据格式 | |||
modelconvert.inputshape=输入张量形状 | |||
modelconvert.inputshapetip=如:1,1,32,32,与输入数据格式对应。 | |||
modelconvert.netoutputdata=网络输出数据类型 | |||
modelconvert.taskdesc=任务描述 | |||
modelconvert.newtask=新建任务 | |||
modelconvert.createtask=创建模型转换任务 | |||
modelconvert.taskurlname=模型转换任务 | |||
log_scroll_start=滚动到顶部 | |||
log_scroll_end=滚动到底部 | |||
modelconvert.tasknameempty=请输入任务名称。 | |||
modelconvert.inputshapeerror=格式输入错误,请输入如:1,1,32,32,与输入数据格式对应。 | |||
modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。 | |||
modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。 | |||
modelconvert.manage.model_not_exist=选择的模型不存在。 | |||
@@ -2978,6 +3045,13 @@ notices.desc=提示描述 | |||
notices.op=操作 | |||
notices.delete_success=系统通知已被删除。 | |||
user_management = 用户管理 | |||
resource_management = 资源管理 | |||
resource_pool = 资源池(队列) | |||
resource_price = 资源规格单价 | |||
application_scenario = 应用场景 | |||
system_configuration = 系统配置 | |||
[action] | |||
create_repo=创建了项目 <a href="%s">%s</a> | |||
rename_repo=重命名项目 <code>%[1]s</code> 为 <a href="%[2]s">%[3]s</a> | |||
@@ -3106,6 +3180,8 @@ all_ai_center=全部智算中心 | |||
resource_cluster = 算力集群 | |||
resource_cluster_openi = 启智集群 | |||
resource_cluster_c2net = 智算网络集群 | |||
resource_cluster_openi_simple = 启智 | |||
resource_cluster_c2net_simple = 智算网络 | |||
compute_resource = 计算资源 | |||
task_name = 任务名称 | |||
task_type = 任务类型 | |||
@@ -3131,7 +3207,8 @@ card_type = 卡类型 | |||
wrong_specification=您目前不能使用这个资源规格,请选择其他资源规格。 | |||
job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。 | |||
dataset_path_rule = 数据集位置存储在环境变量data_url中,训练输出路径存储在环境变量train_url中。 | |||
train_dataset_path_rule = 数据集位置存储在环境变量<strong style="color:#010101">data_url</strong>中,训练输出路径存储在环境变量<strong style="color:#010101">train_url</strong>中。 | |||
infer_dataset_path_rule = 数据集位置存储在环境变量<strong style="color:#010101">data_url</strong>中,推理输出路径存储在环境变量<strong style="color:#010101">result_url</strong>中。 | |||
view_sample = 查看样例 | |||
inference_output_path_rule = 推理输出路径存储在环境变量result_url中。 | |||
model_file_path_rule = 模型文件位置存储在环境变量ckpt_url中。 | |||
@@ -3141,7 +3218,7 @@ delete_task = 删除任务 | |||
task_delete_confirm = 你确认删除该任务么?此任务一旦删除不可恢复。 | |||
operate_confirm = 确定操作 | |||
operate_cancel = 取消操作 | |||
resource_use=资源占用情况 | |||
gpu_num = GPU数 | |||
cpu_num = CPU数 | |||
@@ -3165,3 +3242,5 @@ load_code_failed=代码加载失败,请确认选择了正确的分支。 | |||
error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集 | |||
new_train_gpu_tooltips =训练脚本存储在<strong style="color:#010101">%s</strong>中,数据集存储在<strong style="color:#010101">%s</strong>中,训练输出请存储在<strong style="color:#010101">%s</strong>中以供后续下载。 | |||
new_infer_gpu_tooltips = 数据集存储在<strong style="color:#010101">%s</strong>中,模型文件存储在<strong style="color:#010101">%s</strong>中,推理输出请存储在<strong style="color:#010101">%s</strong>中以供后续下载。 |
@@ -54,6 +54,7 @@ | |||
"vue": "2.6.11", | |||
"vue-bar-graph": "1.2.0", | |||
"vue-calendar-heatmap": "0.8.4", | |||
"vue-i18n": "6.1.3", | |||
"vue-loader": "15.9.2", | |||
"vue-router": "3.3.4", | |||
"vue-template-compiler": "2.6.11", | |||
@@ -0,0 +1,248 @@ | |||
package admin | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/base" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/routers/response" | |||
"code.gitea.io/gitea/services/cloudbrain/resource" | |||
"net/http" | |||
) | |||
const ( | |||
tplResourceQueue base.TplName = "admin/resources/queue" | |||
tplResourceSpecification base.TplName = "admin/resources/specification" | |||
tplResourceScene base.TplName = "admin/resources/scene" | |||
) | |||
func GetQueuePage(ctx *context.Context) { | |||
ctx.Data["PageIsAdmin"] = true | |||
ctx.Data["PageIsAdminResources"] = true | |||
ctx.Data["PageIsAdminResourcesQueue"] = true | |||
ctx.HTML(200, tplResourceQueue) | |||
} | |||
func GetSpecificationPage(ctx *context.Context) { | |||
ctx.Data["PageIsAdmin"] = true | |||
ctx.Data["PageIsAdminResources"] = true | |||
ctx.Data["PageIsAdminResourcesSpecification"] = true | |||
ctx.HTML(200, tplResourceSpecification) | |||
} | |||
func GetScenePage(ctx *context.Context) { | |||
ctx.Data["PageIsAdmin"] = true | |||
ctx.Data["PageIsAdminResources"] = true | |||
ctx.Data["PageIsAdminResourcesScene"] = true | |||
ctx.HTML(200, tplResourceScene) | |||
} | |||
func GetResourceQueueList(ctx *context.Context) { | |||
page := ctx.QueryInt("page") | |||
cluster := ctx.Query("cluster") | |||
aiCenterCode := ctx.Query("center") | |||
computeResource := ctx.Query("resource") | |||
accCardType := ctx.Query("card") | |||
list, err := resource.GetResourceQueueList(models.SearchResourceQueueOptions{ | |||
ListOptions: models.ListOptions{Page: page, PageSize: 10}, | |||
Cluster: cluster, | |||
AiCenterCode: aiCenterCode, | |||
ComputeResource: computeResource, | |||
AccCardType: accCardType, | |||
}) | |||
if err != nil { | |||
log.Error("GetResourceQueueList error.%v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
} | |||
func GetResourceQueueCodes(ctx *context.Context) { | |||
cluster := ctx.Query("cluster") | |||
list, err := resource.GetResourceQueueCodes(models.GetQueueCodesOptions{Cluster: cluster}) | |||
if err != nil { | |||
log.Error("GetResourceQueueCodes error.%v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
} | |||
func GetResourceAiCenters(ctx *context.Context) { | |||
list, err := resource.GetResourceAiCenters() | |||
if err != nil { | |||
log.Error("GetResourceAiCenters error.%v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
} | |||
func AddResourceQueue(ctx *context.Context, req models.ResourceQueueReq) { | |||
req.IsAutomaticSync = false | |||
req.CreatorId = ctx.User.ID | |||
err := resource.AddResourceQueue(req) | |||
if err != nil { | |||
log.Error("AddResourceQueue error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} | |||
func UpdateResourceQueue(ctx *context.Context, req models.ResourceQueueReq) { | |||
queueId := ctx.ParamsInt64(":id") | |||
//only CardsTotalNum permitted to change | |||
err := resource.UpdateResourceQueue(queueId, req) | |||
if err != nil { | |||
log.Error("UpdateResourceQueue error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} | |||
func SyncGrampusQueue(ctx *context.Context) { | |||
err := resource.SyncGrampusQueue(ctx.User.ID) | |||
if err != nil { | |||
log.Error("AddResourceQueue error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} | |||
func GetResourceSpecificationList(ctx *context.Context) { | |||
page := ctx.QueryInt("page") | |||
queue := ctx.QueryInt64("queue") | |||
status := ctx.QueryInt("status") | |||
cluster := ctx.Query("cluster") | |||
list, err := resource.GetResourceSpecificationList(models.SearchResourceSpecificationOptions{ | |||
ListOptions: models.ListOptions{Page: page, PageSize: 10}, | |||
QueueId: queue, | |||
Status: status, | |||
Cluster: cluster, | |||
}) | |||
if err != nil { | |||
log.Error("GetResourceSpecificationList error.%v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
} | |||
func GetResourceSpecificationScenes(ctx *context.Context) { | |||
specId := ctx.ParamsInt64(":id") | |||
list, err := resource.GetResourceSpecificationScenes(specId) | |||
if err != nil { | |||
log.Error("GetResourceSpecificationScenes error.%v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
r := make(map[string]interface{}) | |||
r["List"] = list | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(r)) | |||
} | |||
func AddResourceSpecification(ctx *context.Context, req models.ResourceSpecificationReq) { | |||
req.IsAutomaticSync = false | |||
req.CreatorId = ctx.User.ID | |||
err := resource.AddResourceSpecification(ctx.User.ID, req) | |||
if err != nil { | |||
log.Error("AddResourceQueue error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} | |||
func UpdateResourceSpecification(ctx *context.Context, req models.ResourceSpecificationReq) { | |||
id := ctx.ParamsInt64(":id") | |||
action := ctx.Query("action") | |||
var err *response.BizError | |||
switch action { | |||
case "edit": | |||
if req.UnitPrice < 0 { | |||
ctx.JSON(http.StatusOK, response.ServerError("param error")) | |||
return | |||
} | |||
//only UnitPrice and permitted to change | |||
err = resource.UpdateSpecUnitPrice(ctx.User.ID, id, req.UnitPrice) | |||
case "on-shelf": | |||
err = resource.ResourceSpecOnShelf(ctx.User.ID, id, req.UnitPrice) | |||
case "off-shelf": | |||
err = resource.ResourceSpecOffShelf(ctx.User.ID, id) | |||
} | |||
if err != nil { | |||
log.Error("UpdateResourceSpecification error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ResponseError(err)) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} | |||
func SyncGrampusSpecs(ctx *context.Context) { | |||
err := resource.SyncGrampusSpecs(ctx.User.ID) | |||
if err != nil { | |||
log.Error("AddResourceQueue error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} | |||
func GetResourceSceneList(ctx *context.Context) { | |||
page := ctx.QueryInt("page") | |||
jobType := ctx.Query("jobType") | |||
aiCenterCode := ctx.Query("center") | |||
queueId := ctx.QueryInt64("queue") | |||
isExclusive := ctx.QueryInt("IsExclusive") | |||
list, err := resource.GetResourceSceneList(models.SearchResourceSceneOptions{ | |||
ListOptions: models.ListOptions{Page: page, PageSize: 10}, | |||
JobType: jobType, | |||
IsExclusive: isExclusive, | |||
AiCenterCode: aiCenterCode, | |||
QueueId: queueId, | |||
}) | |||
if err != nil { | |||
log.Error("GetResourceSceneList error.%v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
} | |||
func AddResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||
req.CreatorId = ctx.User.ID | |||
err := resource.AddResourceScene(req) | |||
if err != nil { | |||
log.Error("AddResourceScene error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} | |||
func UpdateResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||
id := ctx.ParamsInt64(":id") | |||
action := ctx.Query("action") | |||
req.ID = id | |||
var err error | |||
switch action { | |||
case "edit": | |||
err = resource.UpdateResourceScene(req) | |||
case "delete": | |||
err = resource.DeleteResourceScene(id) | |||
} | |||
if err != nil { | |||
log.Error("UpdateResourceScene error. %v", err) | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, response.Success()) | |||
} |
@@ -916,6 +916,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Group("/cloudbrain", func() { | |||
m.Get("/:id", repo.GetCloudbrainTask) | |||
m.Get("/:id/log", repo.CloudbrainGetLog) | |||
m.Get("/:id/download_log_file", repo.CloudbrainDownloadLogFile) | |||
m.Group("/train-job", func() { | |||
m.Group("/:jobid", func() { | |||
m.Get("", repo.GetModelArtsTrainJobVersion) | |||
@@ -6,13 +6,17 @@ | |||
package repo | |||
import ( | |||
"code.gitea.io/gitea/modules/notification" | |||
"bufio" | |||
"encoding/json" | |||
"io" | |||
"net/http" | |||
"os" | |||
"sort" | |||
"strings" | |||
"time" | |||
"code.gitea.io/gitea/modules/notification" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/models" | |||
@@ -366,7 +370,7 @@ func CloudbrainForModelConvertGetLog(ctx *context.Context) { | |||
ctx.JSON(http.StatusOK, result) | |||
} | |||
func CloudbrainGetLog(ctx *context.Context) { | |||
func CloudbrainDownloadLogFile(ctx *context.Context) { | |||
ID := ctx.Params(":id") | |||
job, err := models.GetCloudbrainByID(ID) | |||
if err != nil { | |||
@@ -375,13 +379,124 @@ func CloudbrainGetLog(ctx *context.Context) { | |||
return | |||
} | |||
result := CloudbrainGetLogByJobId(job.JobID, job.JobName) | |||
prefix := "/" + setting.CBCodePathPrefix + job.JobName + "/model" | |||
files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | |||
if err != nil { | |||
log.Error("query cloudbrain model failed: %v", err) | |||
return | |||
} | |||
fileName := "" | |||
for _, file := range files { | |||
if strings.HasSuffix(file.FileName, "log.txt") { | |||
fileName = file.FileName | |||
break | |||
} | |||
} | |||
if fileName != "" { | |||
url, err := storage.Attachments.PresignedGetURL(prefix+"/"+fileName, fileName) | |||
if err != nil { | |||
log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"]) | |||
ctx.ServerError("Get minio get SignedUrl failed", err) | |||
return | |||
} | |||
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect) | |||
} | |||
} | |||
func CloudbrainGetLog(ctx *context.Context) { | |||
ID := ctx.Params(":id") | |||
startLine := ctx.QueryInt("base_line") | |||
lines := ctx.QueryInt("lines") | |||
endLine := startLine + lines | |||
order := ctx.Query("order") | |||
if order == "asc" { | |||
endLine = startLine | |||
startLine = endLine - lines | |||
if startLine < 0 { | |||
startLine = 0 | |||
} | |||
} | |||
job, err := models.GetCloudbrainByID(ID) | |||
if err != nil { | |||
log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | |||
ctx.ServerError(err.Error(), err) | |||
return | |||
} | |||
result := getLogFromModelDir(job.JobName, startLine, endLine) | |||
if result == nil { | |||
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"]) | |||
ctx.ServerError(err.Error(), err) | |||
return | |||
} | |||
ctx.JSON(http.StatusOK, result) | |||
re := map[string]interface{}{ | |||
"JobID": ID, | |||
"LogFileName": result["FileName"], | |||
"StartLine": startLine, | |||
"EndLine": result["endLine"], | |||
"Content": result["Content"], | |||
"Lines": result["lines"], | |||
"CanLogDownload": result["FileName"] != "", | |||
} | |||
//result := CloudbrainGetLogByJobId(job.JobID, job.JobName) | |||
ctx.JSON(http.StatusOK, re) | |||
} | |||
func getLogFromModelDir(jobName string, startLine int, endLine int) map[string]interface{} { | |||
prefix := "/" + setting.CBCodePathPrefix + jobName + "/model" | |||
files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | |||
if err != nil { | |||
log.Error("query cloudbrain model failed: %v", err) | |||
return nil | |||
} | |||
re := "" | |||
fileName := "" | |||
count := 0 | |||
fileEndLine := endLine | |||
for _, file := range files { | |||
if strings.HasSuffix(file.FileName, "log.txt") { | |||
fileName = file.FileName | |||
path := storage.GetMinioPath(jobName+"/model/", file.FileName) | |||
log.Info("path=" + path) | |||
reader, err := os.Open(path) | |||
defer reader.Close() | |||
if err == nil { | |||
r := bufio.NewReader(reader) | |||
for i := 0; i < endLine; i++ { | |||
line, error := r.ReadString('\n') | |||
log.Info("line=" + line) | |||
fileEndLine = i | |||
if error == io.EOF { | |||
log.Info("read file completed.") | |||
break | |||
} | |||
if error != nil { | |||
log.Info("read file error." + error.Error()) | |||
break | |||
} | |||
if error == nil { | |||
if i >= startLine { | |||
re = re + line | |||
count++ | |||
} | |||
} | |||
} | |||
} else { | |||
log.Info("error:" + err.Error()) | |||
} | |||
break | |||
} | |||
} | |||
return map[string]interface{}{ | |||
"JobName": jobName, | |||
"Content": re, | |||
"FileName": fileName, | |||
"lines": count, | |||
"endLine": fileEndLine, | |||
} | |||
} | |||
func CloudBrainModelConvertList(ctx *context.APIContext) { | |||
@@ -764,7 +764,7 @@ func GetCloudbrainsDetailData(ctx *context.Context) { | |||
taskDetail.WaitTime = repo.GetCloudbrainWaitTime(ciTasks[i].Cloudbrain) | |||
if ciTasks[i].Cloudbrain.DeletedAt != nilTime { | |||
if ciTasks[i].Cloudbrain.DeletedAt != nilTime || ciTasks[i].Repo == nil { | |||
taskDetail.IsDelete = true | |||
} else { | |||
taskDetail.IsDelete = false | |||
@@ -6,13 +6,14 @@ | |||
package repo | |||
import ( | |||
"code.gitea.io/gitea/modules/notification" | |||
"encoding/json" | |||
"net/http" | |||
"path" | |||
"strconv" | |||
"strings" | |||
"code.gitea.io/gitea/modules/notification" | |||
"code.gitea.io/gitea/modules/grampus" | |||
"code.gitea.io/gitea/modules/setting" | |||
@@ -352,6 +353,14 @@ func DelTrainJobVersion(ctx *context.APIContext) { | |||
return | |||
} | |||
if task.Status != string(models.ModelArtsTrainJobImageFailed) && task.Status != string(models.ModelArtsTrainJobSubmitFailed) && task.Status != string(models.ModelArtsTrainJobDeleteFailed) && | |||
task.Status != string(models.ModelArtsTrainJobCompleted) && task.Status != string(models.ModelArtsTrainJobFailed) && | |||
task.Status != string(models.ModelArtsTrainJobKilled) && task.Status != string(models.ModelArtsTrainJobCanceled) && task.Status != string(models.ModelArtsTrainJobLost) { | |||
log.Error("the job(%s) version has not been stopped", task.JobName) | |||
ctx.NotFound(err) | |||
return | |||
} | |||
//删除modelarts上的记录 | |||
_, err = modelarts.DelTrainJobVersion(jobID, strconv.FormatInt(task.VersionID, 10)) | |||
if err != nil { | |||
@@ -296,11 +296,10 @@ func ExploreDatasets(ctx *context.Context) { | |||
// ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled | |||
var ( | |||
datasets []*models.Dataset | |||
datasetsWithStar []*models.DatasetWithStar | |||
count int64 | |||
err error | |||
orderBy models.SearchOrderBy | |||
datasets []*models.Dataset | |||
count int64 | |||
err error | |||
orderBy models.SearchOrderBy | |||
) | |||
page := ctx.QueryInt("page") | |||
if page <= 0 { | |||
@@ -379,14 +378,6 @@ func ExploreDatasets(ctx *context.Context) { | |||
ctx.ServerError("SearchDatasets", err) | |||
return | |||
} | |||
for _, dataset := range datasets { | |||
if !ctx.IsSigned { | |||
datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: false}) | |||
} else { | |||
datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: models.IsDatasetStaring(ctx.User.ID, dataset.ID)}) | |||
} | |||
} | |||
pager := context.NewPagination(int(count), opts.PageSize, page, 5) | |||
ctx.Data["Keyword"] = opts.Keyword | |||
@@ -397,7 +388,7 @@ func ExploreDatasets(ctx *context.Context) { | |||
pager.SetDefaultParams(ctx) | |||
ctx.Data["Page"] = pager | |||
ctx.Data["Datasets"] = datasetsWithStar | |||
ctx.Data["Datasets"] = repository.ConvertToDatasetWithStar(ctx, datasets) | |||
ctx.Data["Total"] = count | |||
ctx.Data["PageIsDatasets"] = true | |||
ctx.HTML(200, tplExploreDataset) | |||
@@ -928,7 +928,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
} | |||
} | |||
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, false) | |||
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false) | |||
ctx.Data["task"] = task | |||
labelName := strings.Fields(task.LabelName) | |||
ctx.Data["LabelName"] = labelName | |||
@@ -1245,6 +1245,15 @@ func StopJobsByRepoID(repoID int64) { | |||
StopJobs(cloudBrains) | |||
} | |||
func DeleteJobsByRepoID(repoID int64) { | |||
cloudBrains, err := models.GetCloudbrainsNeededDeleteByRepoID(repoID) | |||
if err != nil { | |||
log.Warn("Failed to get cloudBrain info", err) | |||
return | |||
} | |||
DeleteJobs(cloudBrains) | |||
} | |||
/** | |||
*/ | |||
@@ -1280,6 +1289,36 @@ func StopJobs(cloudBrains []*models.Cloudbrain) { | |||
} | |||
} | |||
func DeleteJobs(cloudBrains []*models.Cloudbrain) { | |||
for _, taskInfo := range cloudBrains { | |||
err := models.DeleteJob(taskInfo) | |||
if err != nil { | |||
log.Warn("Failed to DeleteJob:", err) | |||
return | |||
} | |||
if taskInfo.Type == models.TypeCloudBrainOne { | |||
cloudbrain.DelCloudBrainJob(taskInfo.JobName) | |||
DeleteCloudbrainJobStorage(taskInfo.JobName, models.TypeCloudBrainOne) | |||
} | |||
if taskInfo.Type == models.TypeCloudBrainTwo { | |||
if taskInfo.JobType == string(models.JobTypeTrain) || taskInfo.JobType == string(models.JobTypeInference) { | |||
modelarts.DelTrainJob(taskInfo.JobID) | |||
DeleteJobStorage(taskInfo.JobName) | |||
} | |||
if taskInfo.JobType == string(models.JobTypeDebug) { | |||
modelarts.DelNotebook2(taskInfo.JobID) | |||
} | |||
} | |||
if taskInfo.Type == models.TypeC2Net { | |||
if taskInfo.JobType == string(models.JobTypeTrain) { | |||
cloudbrain.DelCloudBrainJob(taskInfo.JobName) | |||
DeleteCloudbrainJobStorage(taskInfo.JobName, models.TypeCloudBrainOne) | |||
} | |||
} | |||
} | |||
} | |||
func retry(attempts int, sleep time.Duration, f func() error) (err error) { | |||
for i := 0; i < attempts; i++ { | |||
if i > 0 { | |||
@@ -1347,7 +1386,7 @@ func deleteCloudbrainJob(ctx *context.Context) error { | |||
return err | |||
} | |||
deleteJobStorage(task.JobName, models.TypeCloudBrainOne) | |||
DeleteCloudbrainJobStorage(task.JobName, models.TypeCloudBrainOne) | |||
return nil | |||
} | |||
@@ -1734,7 +1773,7 @@ func mkPathAndReadMeFile(path string, text string) error { | |||
return nil | |||
} | |||
func deleteJobStorage(jobName string, cloudbrainType int) error { | |||
func DeleteCloudbrainJobStorage(jobName string, cloudbrainType int) error { | |||
//delete local | |||
localJobPath := setting.JobPath + jobName | |||
err := os.RemoveAll(localJobPath) | |||
@@ -2679,7 +2718,7 @@ func getTrainJobCommand(form auth.CreateCloudBrainForm) (string, error) { | |||
} | |||
} | |||
command += "python /code/" + bootFile + param + " > " + cloudbrain.ModelMountPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile | |||
command += "python /code/" + bootFile + param + " | tee " + cloudbrain.ModelMountPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile | |||
return command, nil | |||
} | |||
@@ -9,6 +9,8 @@ import ( | |||
"strings" | |||
"unicode/utf8" | |||
"code.gitea.io/gitea/services/repository" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/auth" | |||
"code.gitea.io/gitea/modules/base" | |||
@@ -22,6 +24,7 @@ const ( | |||
tplDatasetCreate base.TplName = "repo/datasets/create" | |||
tplDatasetEdit base.TplName = "repo/datasets/edit" | |||
taskstplIndex base.TplName = "repo/datasets/tasks/index" | |||
tplReference base.TplName = "repo/datasets/reference" | |||
) | |||
// MustEnableDataset check if repository enable internal dataset | |||
@@ -267,6 +270,37 @@ func CreateDatasetPost(ctx *context.Context, form auth.CreateDatasetForm) { | |||
} | |||
} | |||
func ReferenceDatasetDelete(ctx *context.Context) { | |||
repoID := ctx.Repo.Repository.ID | |||
datasetId, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64) | |||
oldDatasetIds := models.GetDatasetIdsByRepoID(repoID) | |||
var newDatasetIds []int64 | |||
for _, tempDatasetId := range oldDatasetIds { | |||
if datasetId != tempDatasetId { | |||
newDatasetIds = append(newDatasetIds, tempDatasetId) | |||
} | |||
} | |||
err := models.NewDatasetIdsByRepoID(repoID, newDatasetIds) | |||
if err != nil { | |||
ctx.JSON(http.StatusOK, models.BaseErrorMessage("dataset.cancel_reference_dataset_fail")) | |||
} | |||
ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||
} | |||
func ReferenceDatasetPost(ctx *context.Context, form auth.ReferenceDatasetForm) { | |||
repoID := ctx.Repo.Repository.ID | |||
err := models.NewDatasetIdsByRepoID(repoID, form.DatasetID) | |||
if err != nil { | |||
ctx.JSON(http.StatusOK, models.BaseErrorMessage("dataset.reference_dataset_fail")) | |||
} | |||
ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||
} | |||
func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) { | |||
ctx.Data["PageIsDataset"] = true | |||
@@ -412,18 +446,17 @@ func MyDatasets(ctx *context.Context) { | |||
func datasetMultiple(ctx *context.Context, opts *models.SearchDatasetOptions) { | |||
page := ctx.QueryInt("page") | |||
cloudbrainType := ctx.QueryInt("type") | |||
keyword := strings.Trim(ctx.Query("q"), " ") | |||
orderBy := models.SearchOrderByRecentUpdated | |||
opts.Keyword = keyword | |||
opts.SearchOrderBy = orderBy | |||
if opts.SearchOrderBy.String() == "" { | |||
opts.SearchOrderBy = models.SearchOrderByRecentUpdated | |||
} | |||
opts.RecommendOnly = ctx.QueryBool("recommend") | |||
opts.CloudBrainType = cloudbrainType | |||
opts.ListOptions = models.ListOptions{ | |||
Page: page, | |||
PageSize: setting.UI.DatasetPagingNum, | |||
} | |||
opts.NeedAttachment = true | |||
opts.JustNeedZipFile = true | |||
opts.User = ctx.User | |||
@@ -449,22 +482,56 @@ func datasetMultiple(ctx *context.Context, opts *models.SearchDatasetOptions) { | |||
"data": string(data), | |||
"count": strconv.FormatInt(count, 10), | |||
}) | |||
} | |||
func CurrentRepoDatasetMultiple(ctx *context.Context) { | |||
datasetIds := models.GetDatasetIdsByRepoID(ctx.Repo.Repository.ID) | |||
searchOrderBy := getSearchOrderByInValues(datasetIds) | |||
opts := &models.SearchDatasetOptions{ | |||
RepoID: ctx.Repo.Repository.ID, | |||
RepoID: ctx.Repo.Repository.ID, | |||
NeedAttachment: true, | |||
CloudBrainType: ctx.QueryInt("type"), | |||
DatasetIDs: datasetIds, | |||
SearchOrderBy: searchOrderBy, | |||
} | |||
datasetMultiple(ctx, opts) | |||
} | |||
func getSearchOrderByInValues(datasetIds []int64) models.SearchOrderBy { | |||
if len(datasetIds) == 0 { | |||
return "" | |||
} | |||
searchOrderBy := "CASE id " | |||
for i, id := range datasetIds { | |||
searchOrderBy += fmt.Sprintf(" WHEN %d THEN %d", id, i+1) | |||
} | |||
searchOrderBy += " ELSE 0 END" | |||
return models.SearchOrderBy(searchOrderBy) | |||
} | |||
func MyDatasetsMultiple(ctx *context.Context) { | |||
opts := &models.SearchDatasetOptions{ | |||
UploadAttachmentByMe: true, | |||
NeedAttachment: true, | |||
CloudBrainType: ctx.QueryInt("type"), | |||
} | |||
datasetMultiple(ctx, opts) | |||
} | |||
func ReferenceDatasetAvailable(ctx *context.Context) { | |||
opts := &models.SearchDatasetOptions{ | |||
PublicOnly: true, | |||
NeedAttachment: false, | |||
CloudBrainType: models.TypeCloudBrainAll, | |||
} | |||
dataset, _ := models.GetDatasetByRepo(&models.Repository{ID: ctx.Repo.Repository.ID}) | |||
if dataset != nil { | |||
opts.ExcludeDatasetId = dataset.ID | |||
} | |||
datasetMultiple(ctx, opts) | |||
@@ -473,7 +540,9 @@ func MyDatasetsMultiple(ctx *context.Context) { | |||
func PublicDatasetMultiple(ctx *context.Context) { | |||
opts := &models.SearchDatasetOptions{ | |||
PublicOnly: true, | |||
PublicOnly: true, | |||
NeedAttachment: true, | |||
CloudBrainType: ctx.QueryInt("type"), | |||
} | |||
datasetMultiple(ctx, opts) | |||
@@ -482,11 +551,50 @@ func PublicDatasetMultiple(ctx *context.Context) { | |||
func MyFavoriteDatasetMultiple(ctx *context.Context) { | |||
opts := &models.SearchDatasetOptions{ | |||
StarByMe: true, | |||
DatasetIDs: models.GetDatasetIdsStarByUser(ctx.User.ID), | |||
StarByMe: true, | |||
DatasetIDs: models.GetDatasetIdsStarByUser(ctx.User.ID), | |||
NeedAttachment: true, | |||
CloudBrainType: ctx.QueryInt("type"), | |||
} | |||
datasetMultiple(ctx, opts) | |||
} | |||
func ReferenceDataset(ctx *context.Context) { | |||
MustEnableDataset(ctx) | |||
ctx.Data["PageIsDataset"] = true | |||
ctx.Data["MaxReferenceDatasetNum"] = setting.RepoMaxReferenceDatasetNum | |||
ctx.Data["CanWrite"] = ctx.Repo.CanWrite(models.UnitTypeDatasets) | |||
ctx.HTML(200, tplReference) | |||
} | |||
func ReferenceDatasetData(ctx *context.Context) { | |||
MustEnableDataset(ctx) | |||
datasetIds := models.GetDatasetIdsByRepoID(ctx.Repo.Repository.ID) | |||
var datasets models.DatasetList | |||
var err error | |||
if len(datasetIds) > 0 { | |||
opts := &models.SearchDatasetOptions{ | |||
DatasetIDs: datasetIds, | |||
NeedAttachment: false, | |||
CloudBrainType: models.TypeCloudBrainAll, | |||
ListOptions: models.ListOptions{ | |||
Page: 1, | |||
PageSize: setting.RepoMaxReferenceDatasetNum, | |||
}, | |||
SearchOrderBy: getSearchOrderByInValues(datasetIds), | |||
QueryReference: true, | |||
} | |||
datasets, _, err = models.SearchDataset(opts) | |||
if err != nil { | |||
ctx.ServerError("SearchDatasets", err) | |||
return | |||
} | |||
} | |||
ctx.JSON(http.StatusOK, repository.ConvertToDatasetWithStar(ctx, datasets)) | |||
} | |||
func PublicDataset(ctx *context.Context) { | |||
page := ctx.QueryInt("page") | |||
@@ -637,7 +637,7 @@ func deleteGrampusJob(ctx *context.Context) error { | |||
if task.ComputeResource == models.NPUResource { | |||
storageType = models.TypeCloudBrainTwo | |||
} | |||
deleteJobStorage(task.JobName, storageType) | |||
DeleteCloudbrainJobStorage(task.JobName, storageType) | |||
return nil | |||
} | |||
@@ -713,7 +713,7 @@ func GrampusTrainJobShow(ctx *context.Context) { | |||
taskList := make([]*models.Cloudbrain, 0) | |||
taskList = append(taskList, task) | |||
ctx.Data["version_list_task"] = taskList | |||
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, false) | |||
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false) | |||
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | |||
ctx.Data["displayJobName"] = task.DisplayJobName | |||
@@ -767,10 +767,6 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||
command += commandDownload | |||
} | |||
//check download result | |||
commandCheckRes := "bash -c \"[[ $? -eq 0 ]] && exit 0 || exit -1;\";" | |||
command += commandCheckRes | |||
//unzip code & dataset | |||
toolUnzip := "unzip -q '" | |||
if strings.HasSuffix(datasetName, ".tar.gz") { | |||
@@ -779,16 +775,22 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||
commandUnzip := "cd " + workDir + "code;unzip -q master.zip;echo \"start to unzip dataset\";cd " + workDir + "dataset;" + toolUnzip + datasetName + "';" | |||
command += commandUnzip | |||
//check unzip result | |||
commandCheckRes = "bash -c \"[[ $? -eq 0 ]] && exit 0 || exit -1;\";" | |||
command += commandCheckRes | |||
command += "echo \"unzip finished;start to exec code;\";" | |||
// set export | |||
var commandExport string | |||
if processorType == grampus.ProcessorTypeNPU { | |||
commandExport = "export bucket=" + setting.Bucket + " && export remote_path=" + outputRemotePath + ";" | |||
} else if processorType == grampus.ProcessorTypeGPU { | |||
commandExport = "export env=" + setting.Grampus.Env + " && export remote_path=" + outputRemotePath + ";" | |||
} | |||
command += commandExport | |||
//exec code | |||
var parameters models.Parameters | |||
var paramCode string | |||
param := make([]models.Parameter, 0) | |||
if len(paramSrc) != 0 { | |||
err := json.Unmarshal([]byte(paramSrc), ¶meters) | |||
if err != nil { | |||
@@ -797,10 +799,6 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||
} | |||
for _, parameter := range parameters.Parameter { | |||
param = append(param, models.Parameter{ | |||
Label: parameter.Label, | |||
Value: parameter.Value, | |||
}) | |||
paramCode += " --" + parameter.Label + "=" + parameter.Value | |||
} | |||
} | |||
@@ -820,15 +818,15 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||
//upload models | |||
if processorType == grampus.ProcessorTypeNPU { | |||
commandUpload := "cd " + workDir + "script_for_grampus/;./uploader_for_obs " + setting.Bucket + " " + outputRemotePath + " " + workDir + "output/;" | |||
commandUpload := "cd " + workDir + "script_for_grampus/;./uploader_for_npu " + setting.Bucket + " " + outputRemotePath + " " + workDir + "output/;" | |||
command += commandUpload | |||
} else if processorType == grampus.ProcessorTypeGPU { | |||
commandUpload := "cd " + workDir + "script_for_grampus/;./uploader_for_minio " + setting.Grampus.Env + " " + outputRemotePath + " " + workDir + "output/;" | |||
commandUpload := "cd " + workDir + "script_for_grampus/;./uploader_for_gpu " + setting.Grampus.Env + " " + outputRemotePath + " " + workDir + "output/;" | |||
command += commandUpload | |||
} | |||
//check exec result | |||
commandCheckRes = "bash -c \"[[ $result -eq 0 ]] && exit 0 || exit -1\"" | |||
commandCheckRes := "bash -c \"[[ $result -eq 0 ]] && exit 0 || exit -1\"" | |||
command += commandCheckRes | |||
return command, nil | |||
@@ -285,7 +285,7 @@ func NotebookShow(ctx *context.Context) { | |||
datasetDownload := make([]models.DatasetDownload, 0) | |||
if ctx.IsSigned { | |||
if task.Uuid != "" && task.UserID == ctx.User.ID { | |||
datasetDownload = GetCloudBrainDataSetInfo(task.Uuid, true) | |||
datasetDownload = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, true) | |||
} | |||
} | |||
user, err := models.GetUserByID(task.UserID) | |||
@@ -331,36 +331,52 @@ func NotebookShow(ctx *context.Context) { | |||
ctx.HTML(200, tplModelArtsNotebookShow) | |||
} | |||
func GetCloudBrainDataSetInfo(uuid string, isNeedDown bool) []models.DatasetDownload { | |||
func GetCloudBrainDataSetInfo(uuid string, datasetname string, isNeedDown bool) []models.DatasetDownload { | |||
datasetDownload := make([]models.DatasetDownload, 0) | |||
if len(uuid) == 0 { | |||
return datasetDownload | |||
} | |||
uuidList := strings.Split(uuid, ";") | |||
for _, uuidStr := range uuidList { | |||
datasetnameList := strings.Split(datasetname, ";") | |||
for i, uuidStr := range uuidList { | |||
name := "" | |||
link := "" | |||
url := "" | |||
isDelete := false | |||
attachment, err := models.GetAttachmentByUUID(uuidStr) | |||
if err != nil { | |||
log.Error("GetAttachmentByUUID failed:%v", err.Error()) | |||
return datasetDownload | |||
} | |||
dataset, err := models.GetDatasetByID(attachment.DatasetID) | |||
if err != nil { | |||
log.Error("GetDatasetByID failed:%v", err.Error()) | |||
return datasetDownload | |||
} | |||
repo, err := models.GetRepositoryByID(dataset.RepoID) | |||
if err != nil { | |||
log.Error("GetRepositoryByID failed:%v", err.Error()) | |||
return datasetDownload | |||
} | |||
url := "" | |||
if isNeedDown { | |||
url = attachment.S3DownloadURL() | |||
if len(datasetnameList) <= i || len(datasetname) == 0 { | |||
continue | |||
} | |||
name = datasetnameList[i] | |||
isDelete = true | |||
} else { | |||
name = attachment.Name | |||
dataset, err := models.GetDatasetByID(attachment.DatasetID) | |||
if err != nil { | |||
log.Error("GetDatasetByID failed:%v", err.Error()) | |||
} else { | |||
repo, err := models.GetRepositoryByID(dataset.RepoID) | |||
if err != nil { | |||
log.Error("GetRepositoryByID failed:%v", err.Error()) | |||
} else { | |||
link = repo.Link() + "/datasets" | |||
} | |||
} | |||
if isNeedDown { | |||
url = attachment.S3DownloadURL() | |||
} | |||
} | |||
datasetDownload = append(datasetDownload, models.DatasetDownload{ | |||
DatasetName: attachment.Name, | |||
DatasetName: name, | |||
DatasetDownloadLink: url, | |||
RepositoryLink: repo.Link() + "/datasets", | |||
RepositoryLink: link, | |||
IsDelete: isDelete, | |||
}) | |||
} | |||
log.Info("dataset length=" + fmt.Sprint(len(datasetDownload))) | |||
return datasetDownload | |||
} | |||
@@ -502,9 +518,11 @@ func NotebookRestart(ctx *context.Context) { | |||
break | |||
} | |||
id = strconv.FormatInt(newTask.ID, 10) | |||
status = res.Status | |||
resultCode = "0" | |||
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, strconv.FormatInt(newTask.ID, 10), newTask.DisplayJobName, models.ActionCreateDebugNPUTask) | |||
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, newTask.DisplayJobName, models.ActionCreateDebugNPUTask) | |||
break | |||
} | |||
@@ -896,12 +914,12 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||
ctx.Data["display_job_name"] = task.DisplayJobName | |||
ctx.Data["job_name"] = task.JobName | |||
attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||
if err != nil { | |||
ctx.ServerError("GetAllUserAttachments failed:", err) | |||
return err | |||
} | |||
ctx.Data["attachments"] = attachs | |||
// attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||
// if err != nil { | |||
// ctx.ServerError("GetAllUserAttachments failed:", err) | |||
// return err | |||
// } | |||
// ctx.Data["attachments"] = attachs | |||
var resourcePools modelarts.ResourcePool | |||
if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil { | |||
@@ -945,12 +963,19 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||
ctx.ServerError("GetBranches error:", err) | |||
return err | |||
} | |||
_, _, datasetNames, _, err := getDatasUrlListByUUIDS(task.Uuid) | |||
if err != nil { | |||
log.Info("query dataset error," + err.Error()) | |||
//ctx.ServerError("GetAllUserAttachments failed:", err) | |||
//return err | |||
} else { | |||
ctx.Data["dataset_name"] = datasetNames | |||
} | |||
ctx.Data["branches"] = branches | |||
ctx.Data["branch_name"] = task.BranchName | |||
ctx.Data["description"] = task.Description | |||
ctx.Data["boot_file"] = task.BootFile | |||
ctx.Data["dataset_name"] = task.DatasetName | |||
ctx.Data["work_server_number"] = task.WorkServerNumber | |||
ctx.Data["flavor_name"] = task.FlavorName | |||
ctx.Data["engine_name"] = task.EngineName | |||
@@ -1804,7 +1829,7 @@ func TrainJobShow(ctx *context.Context) { | |||
} else { | |||
VersionListTasks[i].Parameters = "" | |||
} | |||
datasetList = append(datasetList, GetCloudBrainDataSetInfo(task.Uuid, false)) | |||
datasetList = append(datasetList, GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)) | |||
VersionListTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | |||
VersionListTasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) | |||
} | |||
@@ -1839,6 +1864,16 @@ func TrainJobDel(ctx *context.Context) { | |||
return | |||
} | |||
for _, task := range VersionListTasks { | |||
if task.Status != string(models.ModelArtsTrainJobImageFailed) && task.Status != string(models.ModelArtsTrainJobSubmitFailed) && task.Status != string(models.ModelArtsTrainJobDeleteFailed) && | |||
task.Status != string(models.ModelArtsTrainJobCompleted) && task.Status != string(models.ModelArtsTrainJobFailed) && | |||
task.Status != string(models.ModelArtsTrainJobKilled) && task.Status != string(models.ModelArtsTrainJobCanceled) && task.Status != string(models.ModelArtsTrainJobLost) { | |||
log.Error("the job(%s) version has not been stopped", task.JobName) | |||
ctx.RenderWithErr("the job version has not been stopped", tplModelArtsTrainJobIndex, nil) | |||
return | |||
} | |||
} | |||
//删除modelarts上的任务记录 | |||
_, err = modelarts.DelTrainJob(jobID) | |||
if err != nil { | |||
@@ -1972,7 +2007,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath | |||
resultObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.ResultPath + VersionOutputPath + "/" | |||
logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/" | |||
dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/" | |||
//dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/" | |||
branchName := form.BranchName | |||
FlavorName := form.FlavorName | |||
EngineName := form.EngineName | |||
@@ -2088,6 +2123,28 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
Label: modelarts.CkptUrl, | |||
Value: "s3:/" + ckptUrl, | |||
}) | |||
datasUrlList, dataUrl, datasetNames, isMultiDataset, err := getDatasUrlListByUUIDS(uuid) | |||
if err != nil { | |||
inferenceJobErrorNewDataPrepare(ctx, form) | |||
ctx.RenderWithErr(ctx.Tr(errStr), tplModelArtsInferenceJobNew, &form) | |||
return | |||
} | |||
dataPath := dataUrl | |||
jsondatas, err := json.Marshal(datasUrlList) | |||
if err != nil { | |||
log.Error("Failed to Marshal: %v", err) | |||
inferenceJobErrorNewDataPrepare(ctx, form) | |||
ctx.RenderWithErr("json error:"+err.Error(), tplModelArtsInferenceJobNew, &form) | |||
return | |||
} | |||
if isMultiDataset { | |||
param = append(param, models.Parameter{ | |||
Label: modelarts.MultiDataUrl, | |||
Value: string(jsondatas), | |||
}) | |||
} | |||
existDeviceTarget := false | |||
if len(params) != 0 { | |||
err := json.Unmarshal([]byte(params), ¶meters) | |||
@@ -2146,6 +2203,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
ModelVersion: modelVersion, | |||
CkptName: ckptName, | |||
ResultUrl: resultObsPath, | |||
DatasetName: datasetNames, | |||
} | |||
err = modelarts.GenerateInferenceJob(ctx, req) | |||
@@ -2487,7 +2545,7 @@ func InferenceJobShow(ctx *context.Context) { | |||
ctx.Data["displayJobName"] = task.DisplayJobName | |||
ctx.Data["task"] = task | |||
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | |||
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, false) | |||
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false) | |||
tempUids := []int64{} | |||
tempUids = append(tempUids, task.UserID) | |||
JobCreater, err := models.GetUserNamesByIDs(tempUids) | |||
@@ -2700,11 +2758,23 @@ func getDatasUrlListByUUIDS(uuidStr string) ([]models.Datasurl, string, string, | |||
datasetInfos := make(map[string]models.DatasetInfo) | |||
attachs, err := models.GetAttachmentsByUUIDs(uuids) | |||
if err != nil { | |||
if err != nil || len(attachs) != len(uuids) { | |||
log.Error("GetAttachmentsByUUIDs failed: %v", err) | |||
return datasUrlList, dataUrl, datasetNames, isMultiDataset, errors.New("GetAttachmentsByUUIDs failed") | |||
} | |||
for i, attach := range attachs { | |||
for i, tmpUuid := range uuids { | |||
var attach *models.Attachment | |||
for _, tmpAttach := range attachs { | |||
if tmpAttach.UUID == tmpUuid { | |||
attach = tmpAttach | |||
break | |||
} | |||
} | |||
if attach == nil { | |||
log.Error("GetAttachmentsByUUIDs failed: %v", err) | |||
return datasUrlList, dataUrl, datasetNames, isMultiDataset, errors.New("GetAttachmentsByUUIDs failed") | |||
} | |||
fileName := strings.TrimSuffix(strings.TrimSuffix(strings.TrimSuffix(attach.Name, ".zip"), ".tar.gz"), ".tgz") | |||
for _, datasetInfo := range datasetInfos { | |||
if fileName == datasetInfo.Name { | |||
@@ -464,6 +464,16 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { | |||
} | |||
return | |||
} | |||
dataset, err := models.GetDatasetByRepo(repo) | |||
if err == nil { | |||
if dataset != nil { | |||
models.UpdateDatasetCreateUser(dataset.ID, newOwner) | |||
} else { | |||
log.Info("not found the dataset") | |||
} | |||
} else { | |||
log.Info("error=" + err.Error()) | |||
} | |||
log.Trace("Repository transferred: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newOwner) | |||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed")) | |||
@@ -494,7 +504,8 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { | |||
return | |||
} | |||
log.Trace("Repository deleted: %s/%s", ctx.Repo.Owner.Name, repo.Name) | |||
go StopJobsByRepoID(repo.ID) | |||
// go StopJobsByRepoID(repo.ID) | |||
go DeleteJobsByRepoID(repo.ID) | |||
ctx.Flash.Success(ctx.Tr("repo.settings.deletion_success")) | |||
ctx.Redirect(ctx.Repo.Owner.DashboardLink()) | |||
@@ -0,0 +1,14 @@ | |||
package response | |||
type BizError struct { | |||
Code int | |||
Err string | |||
} | |||
func (b BizError) Error() string { | |||
return b.Err | |||
} | |||
func NewBizError(err error) *BizError { | |||
return &BizError{Code: RESPONSE_CODE_ERROR_DEFAULT, Err: err.Error()} | |||
} |
@@ -24,8 +24,12 @@ func ServerError(msg string) *AiforgeResponse { | |||
return &AiforgeResponse{Code: RESPONSE_CODE_ERROR_DEFAULT, Msg: msg} | |||
} | |||
func ResponseError(err *BizError) *AiforgeResponse { | |||
return &AiforgeResponse{Code: err.Code, Msg: err.Err} | |||
} | |||
func SuccessWithData(data interface{}) *AiforgeResponse { | |||
return &AiforgeResponse{Code: RESPONSE_CODE_ERROR_DEFAULT, Msg: RESPONSE_MSG_SUCCESS, Data: data} | |||
return &AiforgeResponse{Code: RESPONSE_CODE_SUCCESS, Msg: RESPONSE_MSG_SUCCESS, Data: data} | |||
} | |||
func ErrorWithData(code int, msg string, data interface{}) *AiforgeResponse { | |||
return &AiforgeResponse{Code: code, Msg: msg, Data: data} | |||
@@ -0,0 +1,4 @@ | |||
package response | |||
var RESOURCE_QUEUE_NOT_AVAILABLE = &BizError{Code: 1001, Err: "resource queue not available"} | |||
var SPECIFICATION_NOT_EXIST = &BizError{Code: 1002, Err: "specification not exist"} |
@@ -605,6 +605,32 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Post("/delete", admin.DeleteNotices) | |||
m.Post("/empty", admin.EmptyNotices) | |||
}) | |||
m.Group("/resources", func() { | |||
m.Group("/queue", func() { | |||
m.Get("", admin.GetQueuePage) | |||
m.Get("/list", admin.GetResourceQueueList) | |||
m.Post("/grampus/sync", admin.SyncGrampusQueue) | |||
m.Get("/codes", admin.GetResourceQueueCodes) | |||
m.Get("/centers", admin.GetResourceAiCenters) | |||
m.Post("/add", binding.Bind(models.ResourceQueueReq{}), admin.AddResourceQueue) | |||
m.Post("/update/:id", binding.BindIgnErr(models.ResourceQueueReq{}), admin.UpdateResourceQueue) | |||
}) | |||
m.Group("/specification", func() { | |||
m.Get("", admin.GetSpecificationPage) | |||
m.Get("/list", admin.GetResourceSpecificationList) | |||
m.Get("/scenes/:id", admin.GetResourceSpecificationScenes) | |||
m.Post("/grampus/sync", admin.SyncGrampusSpecs) | |||
m.Post("/add", binding.Bind(models.ResourceSpecificationReq{}), admin.AddResourceSpecification) | |||
m.Post("/update/:id", binding.BindIgnErr(models.ResourceSpecificationReq{}), admin.UpdateResourceSpecification) | |||
}) | |||
m.Group("/scene", func() { | |||
m.Get("", admin.GetScenePage) | |||
m.Get("/list", admin.GetResourceSceneList) | |||
m.Post("/add", binding.Bind(models.ResourceSceneReq{}), admin.AddResourceScene) | |||
m.Post("/update/:id", binding.BindIgnErr(models.ResourceSceneReq{}), admin.UpdateResourceScene) | |||
}) | |||
}) | |||
}, adminReq) | |||
// ***** END: Admin ***** | |||
@@ -676,6 +702,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
reqRepoIssuesOrPullsReader := context.RequireRepoReaderOr(models.UnitTypeIssues, models.UnitTypePullRequests) | |||
reqRepoDatasetReader := context.RequireRepoReader(models.UnitTypeDatasets) | |||
reqRepoDatasetWriter := context.RequireRepoWriter(models.UnitTypeDatasets) | |||
reqRepoDatasetReaderJson := context.RequireRepoReaderJson(models.UnitTypeDatasets) | |||
reqRepoDatasetWriterJson := context.RequireRepoWriterJson(models.UnitTypeDatasets) | |||
reqRepoCloudBrainReader := context.RequireRepoReader(models.UnitTypeCloudBrain) | |||
reqRepoCloudBrainWriter := context.RequireRepoWriter(models.UnitTypeCloudBrain) | |||
reqRepoModelManageReader := context.RequireRepoReader(models.UnitTypeModelManage) | |||
@@ -1032,10 +1061,14 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Group("/datasets", func() { | |||
m.Get("", reqRepoDatasetReader, repo.DatasetIndex) | |||
m.Get("/reference_datasets", reqRepoDatasetReader, repo.ReferenceDataset) | |||
m.Get("/reference_datasets_data", reqRepoDatasetReaderJson, repo.ReferenceDatasetData) | |||
m.Delete("/reference_datasets/:id", reqRepoDatasetWriterJson, repo.ReferenceDatasetDelete) | |||
m.Put("/:id/:action", reqRepoDatasetReader, repo.DatasetAction) | |||
m.Get("/create", reqRepoDatasetWriter, repo.CreateDataset) | |||
m.Post("/create", reqRepoDatasetWriter, bindIgnErr(auth.CreateDatasetForm{}), repo.CreateDatasetPost) | |||
m.Get("/edit/:id", reqRepoDatasetWriter, repo.EditDataset) | |||
m.Post("/reference_datasets", reqRepoDatasetWriterJson, bindIgnErr(auth.ReferenceDatasetForm{}), repo.ReferenceDatasetPost) | |||
m.Post("/edit", reqRepoDatasetWriter, bindIgnErr(auth.EditDatasetForm{}), repo.EditDatasetPost) | |||
m.Get("/current_repo", repo.CurrentRepoDataset) | |||
m.Get("/my_datasets", repo.MyDatasets) | |||
@@ -1045,6 +1078,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("/current_repo_m", repo.CurrentRepoDatasetMultiple) | |||
m.Get("/my_datasets_m", repo.MyDatasetsMultiple) | |||
m.Get("/public_datasets_m", repo.PublicDatasetMultiple) | |||
m.Get("/reference_datasets_available", repo.ReferenceDatasetAvailable) | |||
m.Get("/my_favorite_m", repo.MyFavoriteDatasetMultiple) | |||
m.Group("/status", func() { | |||
@@ -1100,7 +1135,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("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.TrainJobNewVersion) | |||
//m.Get("/get_log", cloudbrain.AdminOrJobCreaterRightForTrain, repo.GetLogFromModelDir) | |||
//m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) | |||
}) | |||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.CloudBrainTrainJobNew) | |||
@@ -1184,7 +1219,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("", reqRepoCloudBrainReader, repo.NotebookShow) | |||
m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.NotebookDebug2) | |||
m.Post("/restart", cloudbrain.AdminOrJobCreaterRight, repo.NotebookRestart) | |||
m.Post("/stop", cloudbrain.AdminOrJobCreaterRight, repo.NotebookStop) | |||
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookStop) | |||
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookDel) | |||
}) | |||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.NotebookNew) | |||
@@ -0,0 +1,14 @@ | |||
package operate_log | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
) | |||
func Log(log models.AdminOperateLog) error { | |||
_, err := models.InsertAdminOperateLog(log) | |||
return err | |||
} | |||
func NewLogValues() *models.LogValues { | |||
return &models.LogValues{Params: make([]models.LogValue, 0)} | |||
} |
@@ -0,0 +1,122 @@ | |||
package resource | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/grampus" | |||
"code.gitea.io/gitea/modules/log" | |||
"fmt" | |||
"strings" | |||
) | |||
func AddResourceQueue(req models.ResourceQueueReq) error { | |||
if _, err := models.InsertResourceQueue(req.ToDTO()); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func UpdateResourceQueue(queueId int64, req models.ResourceQueueReq) error { | |||
if _, err := models.UpdateResourceQueueById(queueId, models.ResourceQueue{ | |||
CardsTotalNum: req.CardsTotalNum, | |||
Remark: req.Remark, | |||
}); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func GetResourceQueueList(opts models.SearchResourceQueueOptions) (*models.ResourceQueueListRes, error) { | |||
n, r, err := models.SearchResourceQueue(opts) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return models.NewResourceQueueListRes(n, r), nil | |||
} | |||
func GetResourceQueueCodes(opts models.GetQueueCodesOptions) ([]*models.ResourceQueueCodesRes, error) { | |||
r, err := models.GetResourceQueueCodes(opts) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return r, nil | |||
} | |||
func GetResourceAiCenters() ([]models.ResourceAiCenterRes, error) { | |||
r, err := models.GetResourceAiCenters() | |||
if err != nil { | |||
return nil, err | |||
} | |||
return r, nil | |||
} | |||
func SyncGrampusQueue(doerId int64) error { | |||
r, err := grampus.GetAiCenters(1, 100) | |||
if err != nil { | |||
return err | |||
} | |||
log.Info("SyncGrampusQueue result = %+v", r) | |||
queueUpdateList := make([]models.ResourceQueue, 0) | |||
queueInsertList := make([]models.ResourceQueue, 0) | |||
existIds := make([]int64, 0) | |||
for _, center := range r.Infos { | |||
for _, device := range center.AccDevices { | |||
computeResource := models.ParseComputeResourceFormGrampus(device.Kind) | |||
accCardType := strings.ToUpper(device.Model) | |||
if computeResource == "" { | |||
continue | |||
} | |||
//Determine if this quque already exists.if exist,update params | |||
//if not exist,insert a new record | |||
oldQueue, err := models.GetResourceQueue(&models.ResourceQueue{ | |||
Cluster: models.C2NetCluster, | |||
AiCenterCode: center.Id, | |||
ComputeResource: computeResource, | |||
AccCardType: accCardType, | |||
}) | |||
if err != nil { | |||
return err | |||
} | |||
if oldQueue == nil { | |||
queueInsertList = append(queueInsertList, models.ResourceQueue{ | |||
Cluster: models.C2NetCluster, | |||
AiCenterCode: center.Id, | |||
AiCenterName: center.Name, | |||
ComputeResource: computeResource, | |||
AccCardType: accCardType, | |||
IsAutomaticSync: true, | |||
CreatedBy: doerId, | |||
UpdatedBy: doerId, | |||
}) | |||
} else { | |||
existIds = append(existIds, oldQueue.ID) | |||
queueUpdateList = append(queueUpdateList, models.ResourceQueue{ | |||
ID: oldQueue.ID, | |||
ComputeResource: computeResource, | |||
AiCenterName: center.Name, | |||
AccCardType: accCardType, | |||
UpdatedBy: doerId, | |||
}) | |||
} | |||
} | |||
} | |||
return models.SyncGrampusQueues(queueUpdateList, queueInsertList, existIds) | |||
} | |||
func SyncGrampusQueueAndSpecs() { | |||
defer func() { | |||
if err := recover(); err != nil { | |||
combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2)) | |||
log.Error("PANIC:", combinedErr) | |||
} | |||
}() | |||
log.Info("start to sync grampus queue and specs") | |||
SyncGrampusQueue(0) | |||
SyncGrampusSpecs(0) | |||
log.Info("sync grampus queue and specs finished") | |||
} |
@@ -0,0 +1,35 @@ | |||
package resource | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
) | |||
func AddResourceScene(req models.ResourceSceneReq) error { | |||
if err := models.InsertResourceScene(req); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func UpdateResourceScene(req models.ResourceSceneReq) error { | |||
if err := models.UpdateResourceScene(req); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func DeleteResourceScene(id int64) error { | |||
if err := models.DeleteResourceScene(id); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func GetResourceSceneList(opts models.SearchResourceSceneOptions) (*models.ResourceSceneListRes, error) { | |||
n, r, err := models.SearchResourceScene(opts) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return models.NewResourceSceneListRes(n, r), nil | |||
} |
@@ -0,0 +1,186 @@ | |||
package resource | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/grampus" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/routers/response" | |||
"code.gitea.io/gitea/services/admin/operate_log" | |||
"fmt" | |||
"strings" | |||
) | |||
func AddResourceSpecification(doerId int64, req models.ResourceSpecificationReq) error { | |||
if req.Status == 0 { | |||
req.Status = models.SpecNotVerified | |||
} | |||
spec := req.ToDTO() | |||
if _, err := models.InsertResourceSpecification(spec); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func UpdateSpecUnitPrice(doerId int64, specId int64, unitPrice int) *response.BizError { | |||
oldSpec, err := models.GetResourceSpecification(&models.ResourceSpecification{ID: specId}) | |||
if err != nil { | |||
return response.NewBizError(err) | |||
} | |||
if oldSpec == nil { | |||
return response.SPECIFICATION_NOT_EXIST | |||
} | |||
err = models.UpdateSpecUnitPriceById(specId, unitPrice) | |||
if err != nil { | |||
return response.NewBizError(err) | |||
} | |||
if oldSpec.UnitPrice != unitPrice { | |||
AddSpecOperateLog(doerId, "edit", operate_log.NewLogValues().Add("unitPrice", unitPrice), operate_log.NewLogValues().Add("unitPrice", oldSpec.UnitPrice), specId, fmt.Sprintf("修改资源规格单价从%d积分到%d积分", oldSpec.UnitPrice, unitPrice)) | |||
} | |||
return nil | |||
} | |||
func SyncGrampusSpecs(doerId int64) error { | |||
r, err := grampus.GetResourceSpecs("") | |||
if err != nil { | |||
return err | |||
} | |||
log.Info("SyncGrampusSpecs result = %+v", r) | |||
specUpdateList := make([]models.ResourceSpecification, 0) | |||
specInsertList := make([]models.ResourceSpecification, 0) | |||
existIds := make([]int64, 0) | |||
for _, spec := range r.Infos { | |||
for _, c := range spec.Centers { | |||
computeResource := models.ParseComputeResourceFormGrampus(spec.SpecInfo.AccDeviceKind) | |||
if computeResource == "" { | |||
continue | |||
} | |||
accCardType := strings.ToUpper(spec.SpecInfo.AccDeviceModel) | |||
memGiB, err := models.ParseMemSizeFromGrampus(spec.SpecInfo.MemorySize) | |||
gpuMemGiB, err := models.ParseMemSizeFromGrampus(spec.SpecInfo.AccDeviceMemory) | |||
if err != nil { | |||
log.Error("ParseMemSizeFromGrampus error. MemorySize=%s AccDeviceMemory=%s", spec.SpecInfo.MemorySize, spec.SpecInfo.AccDeviceMemory) | |||
} | |||
// get resource queue.if queue not exist,skip it | |||
r, err := models.GetResourceQueue(&models.ResourceQueue{ | |||
Cluster: models.C2NetCluster, | |||
AiCenterCode: c.ID, | |||
ComputeResource: computeResource, | |||
AccCardType: accCardType, | |||
}) | |||
if err != nil || r == nil { | |||
continue | |||
} | |||
//Determine if this specification already exists.if exist,update params | |||
//if not exist,insert a new record and status is SpecNotVerified | |||
oldSpec, err := models.GetResourceSpecification(&models.ResourceSpecification{ | |||
QueueId: r.ID, | |||
SourceSpecId: spec.ID, | |||
}) | |||
if err != nil { | |||
return err | |||
} | |||
if oldSpec == nil { | |||
specInsertList = append(specInsertList, models.ResourceSpecification{ | |||
QueueId: r.ID, | |||
SourceSpecId: spec.ID, | |||
AccCardsNum: spec.SpecInfo.AccDeviceNum, | |||
CpuCores: spec.SpecInfo.CpuCoreNum, | |||
MemGiB: memGiB, | |||
GPUMemGiB: gpuMemGiB, | |||
Status: models.SpecNotVerified, | |||
IsAutomaticSync: true, | |||
CreatedBy: doerId, | |||
UpdatedBy: doerId, | |||
}) | |||
} else { | |||
existIds = append(existIds, oldSpec.ID) | |||
specUpdateList = append(specUpdateList, models.ResourceSpecification{ | |||
ID: oldSpec.ID, | |||
AccCardsNum: spec.SpecInfo.AccDeviceNum, | |||
CpuCores: spec.SpecInfo.CpuCoreNum, | |||
MemGiB: memGiB, | |||
GPUMemGiB: gpuMemGiB, | |||
UpdatedBy: doerId, | |||
}) | |||
} | |||
} | |||
} | |||
return models.SyncGrampusSpecs(specUpdateList, specInsertList, existIds) | |||
} | |||
//GetResourceSpecificationList returns specification and queue | |||
func GetResourceSpecificationList(opts models.SearchResourceSpecificationOptions) (*models.ResourceSpecAndQueueListRes, error) { | |||
n, r, err := models.SearchResourceSpecification(opts) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return models.NewResourceSpecAndQueueListRes(n, r), nil | |||
} | |||
func GetResourceSpecificationScenes(specId int64) ([]models.ResourceSceneBriefRes, error) { | |||
r, err := models.GetSpecScenes(specId) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return r, nil | |||
} | |||
func ResourceSpecOnShelf(doerId int64, id int64, unitPrice int) *response.BizError { | |||
spec, err := models.GetResourceSpecification(&models.ResourceSpecification{ID: id}) | |||
if err != nil { | |||
return response.NewBizError(err) | |||
} | |||
if spec == nil { | |||
return response.SPECIFICATION_NOT_EXIST | |||
} | |||
if q, err := models.GetResourceQueue(&models.ResourceQueue{ID: spec.QueueId}); err != nil || q == nil { | |||
return response.RESOURCE_QUEUE_NOT_AVAILABLE | |||
} | |||
err = models.ResourceSpecOnShelf(id, unitPrice) | |||
if err != nil { | |||
return response.NewBizError(err) | |||
} | |||
if spec.UnitPrice != unitPrice { | |||
AddSpecOperateLog(doerId, "on-shelf", operate_log.NewLogValues().Add("UnitPrice", unitPrice), operate_log.NewLogValues().Add("UnitPrice", spec.UnitPrice), id, fmt.Sprintf("定价上架资源规格,单价为%d", unitPrice)) | |||
} else { | |||
AddSpecOperateLog(doerId, "on-shelf", nil, nil, id, "上架资源规格") | |||
} | |||
return nil | |||
} | |||
func ResourceSpecOffShelf(doerId int64, id int64) *response.BizError { | |||
_, err := models.ResourceSpecOffShelf(id) | |||
if err != nil { | |||
return response.NewBizError(err) | |||
} | |||
AddSpecOperateLog(doerId, "off-shelf", nil, nil, id, "下架资源规格") | |||
return nil | |||
} | |||
func AddSpecOperateLog(doerId int64, operateType string, newValue, oldValue *models.LogValues, specId int64, comment string) { | |||
var newString = "" | |||
var oldString = "" | |||
if newValue != nil { | |||
newString = newValue.JsonString() | |||
} | |||
if oldValue != nil { | |||
oldString = oldValue.JsonString() | |||
} | |||
operate_log.Log(models.AdminOperateLog{ | |||
BizType: "SpecOperate", | |||
OperateType: operateType, | |||
OldValue: oldString, | |||
NewValue: newString, | |||
RelatedId: fmt.Sprint(specId), | |||
CreatedBy: doerId, | |||
Comment: comment, | |||
}) | |||
} |
@@ -0,0 +1,19 @@ | |||
package repository | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/context" | |||
) | |||
func ConvertToDatasetWithStar(ctx *context.Context, datasets []*models.Dataset) []*models.DatasetWithStar { | |||
var datasetsWithStar []*models.DatasetWithStar | |||
for _, dataset := range datasets { | |||
if !ctx.IsSigned { | |||
datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: false}) | |||
} else { | |||
datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: models.IsDatasetStaring(ctx.User.ID, dataset.ID)}) | |||
} | |||
} | |||
return datasetsWithStar | |||
} |
@@ -13,10 +13,9 @@ | |||
<div class="alert"></div> | |||
<div class="admin user"> | |||
{{template "admin/navbar" .}} | |||
<div id="images-admin"> | |||
</div> | |||
<div class="ui container"> | |||
<div id="images-admin"></div> | |||
</div> | |||
</div> | |||
<!-- 确认模态框 --> | |||
<div> | |||
@@ -22,19 +22,19 @@ | |||
data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" | |||
data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"></div> | |||
{{template "admin/navbar" .}} | |||
<div class="ui container" style="width: 95%;"> | |||
<div class="ui container"> | |||
{{template "base/alert" .}} | |||
<div class="ui grid"> | |||
<div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | |||
<div class="ui grid" style="margin:0"> | |||
<div class="row" style="border: 1px solid #d4d4d5;margin-top: 0px;padding-top: 0;"> | |||
{{template "admin/cloudbrain/search" .}} | |||
<div class="ui six wide column right aligned" style="margin: 1rem 0;"> | |||
<a class="ui compact blue basic icon button" style="box-shadow: none !important; padding: 0.8em;" | |||
href="/admin/cloudbrains/download"><i | |||
class="ri-download-line middle aligned icon"></i>{{.i18n.Tr "admin.cloudbrain.download_report"}}</a> | |||
</div> | |||
<div class="ui sixteen wide column"> | |||
<div class="ui sixteen wide column" style="overflow-x:auto;"> | |||
<!-- 任务展示 --> | |||
<div class="dataset list"> | |||
<div class="dataset list" style="min-width:2100px;margin-top:15px;margin-bottom:15px;"> | |||
<!-- 表头 --> | |||
<div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
<div class="row"> | |||
@@ -412,17 +412,16 @@ | |||
</div> | |||
{{end}} | |||
{{end}} | |||
<div id="app" style="margin-top: 2rem;"> | |||
<div class="center"> | |||
<el-pagination background @current-change="handleCurrentChange" :current-page="page" | |||
:page-sizes="[10]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" | |||
:total="{{.Page.Paginater.Total}}"> | |||
</el-pagination> | |||
</div> | |||
</div> | |||
{{end}} | |||
</div> | |||
</div> | |||
<div id="app" style="margin-top: 2rem;width:100%;"> | |||
<div class="center"> | |||
<el-pagination background @current-change="handleCurrentChange" :current-page="page" | |||
:page-sizes="[10]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" | |||
:total="{{.Page.Paginater.Total}}"> | |||
</el-pagination> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -1,44 +1,64 @@ | |||
<div class="ui secondary pointing tabular top attached borderless menu stackable new-menu navbar"> | |||
<a class="{{if .PageIsAdminDashboard}}active{{end}} item" href="{{AppSubUrl}}/admin"> | |||
{{.i18n.Tr "admin.dashboard"}} | |||
</a> | |||
<a class="{{if .PageIsAdminUsers}}active{{end}} item" href="{{AppSubUrl}}/admin/users"> | |||
{{.i18n.Tr "admin.users"}} | |||
</a> | |||
<a class="{{if .PageIsAdminOrganizations}}active{{end}} item" href="{{AppSubUrl}}/admin/orgs"> | |||
{{.i18n.Tr "admin.organizations"}} | |||
</a> | |||
<a class="{{if .PageIsAdminRepositories}}active{{end}} item" href="{{AppSubUrl}}/admin/repos"> | |||
{{.i18n.Tr "admin.repositories"}} | |||
</a> | |||
<a class="{{if .PageIsAdminDatasets}}active{{end}} item" href="{{AppSubUrl}}/admin/datasets"> | |||
{{.i18n.Tr "admin.datasets"}} | |||
</a> | |||
<a class="{{if .PageIsAdminCloudBrains}}active{{end}} item" href="{{AppSubUrl}}/admin/cloudbrains"> | |||
{{.i18n.Tr "repo.cloudbrain.task"}} | |||
</a> | |||
<a class="{{if .PageIsAdminImages}}active{{end}} item" href="{{AppSubUrl}}/admin/images"> | |||
{{.i18n.Tr "explore.images"}} | |||
</a> | |||
<a class="{{if .PageIsAdminHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks"> | |||
{{.i18n.Tr "admin.hooks"}} | |||
</a> | |||
<a class="{{if .PageIsAdminSystemHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/system-hooks"> | |||
{{.i18n.Tr "admin.systemhooks"}} | |||
</a> | |||
<a class="{{if .PageIsAdminAuthentications}}active{{end}} item" href="{{AppSubUrl}}/admin/auths"> | |||
{{.i18n.Tr "admin.authentication"}} | |||
</a> | |||
<a class="{{if .PageIsAdminEmails}}active{{end}} item" href="{{AppSubUrl}}/admin/emails"> | |||
{{.i18n.Tr "admin.emails"}} | |||
</a> | |||
<a class="{{if .PageIsAdminConfig}}active{{end}} item" href="{{AppSubUrl}}/admin/config"> | |||
{{.i18n.Tr "admin.config"}} | |||
</a> | |||
<a class="{{if .PageIsAdminNotices}}active{{end}} item" href="{{AppSubUrl}}/admin/notices"> | |||
{{.i18n.Tr "admin.notices"}} | |||
</a> | |||
<a class="{{if .PageIsAdminMonitor}}active{{end}} item" href="{{AppSubUrl}}/admin/monitor"> | |||
{{.i18n.Tr "admin.monitor"}} | |||
</a> | |||
<div class="ui secondary pointing tabular top attached borderless menu stackable new-menu navbar" style="margin-top:0"> | |||
<div class="item-container"> | |||
<a class="{{if .PageIsAdminDashboard}}active{{end}} item" href="{{AppSubUrl}}/admin"> | |||
{{.i18n.Tr "admin.dashboard"}} | |||
</a> | |||
<a class="item item-first" href="javascript:void(0);"> | |||
{{.i18n.Tr "admin.user_management"}} | |||
</a> | |||
<a class="{{if .PageIsAdminUsers}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/users"> | |||
{{.i18n.Tr "admin.users"}} | |||
</a> | |||
<a class="{{if .PageIsAdminEmails}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/emails"> | |||
{{.i18n.Tr "admin.emails"}} | |||
</a> | |||
<a class="{{if .PageIsAdminOrganizations}}active{{end}} item" href="{{AppSubUrl}}/admin/orgs"> | |||
{{.i18n.Tr "admin.organizations"}} | |||
</a> | |||
<a class="{{if .PageIsAdminRepositories}}active{{end}} item" href="{{AppSubUrl}}/admin/repos"> | |||
{{.i18n.Tr "admin.repositories"}} | |||
</a> | |||
<a class="{{if .PageIsAdminDatasets}}active{{end}} item" href="{{AppSubUrl}}/admin/datasets"> | |||
{{.i18n.Tr "admin.datasets"}} | |||
</a> | |||
<a class="{{if .PageIsAdminCloudBrains}}active{{end}} item" href="{{AppSubUrl}}/admin/cloudbrains"> | |||
{{.i18n.Tr "repo.cloudbrain.task"}} | |||
</a> | |||
<a class="{{if .PageIsAdminImages}}active{{end}} item" href="{{AppSubUrl}}/admin/images"> | |||
{{.i18n.Tr "explore.images"}} | |||
</a> | |||
<a class="item item-first" href="javascript:void(0);"> | |||
{{.i18n.Tr "admin.resource_management"}} | |||
</a> | |||
<a class="{{if .PageIsAdminResourcesQueue}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/resources/queue"> | |||
{{.i18n.Tr "admin.resource_pool"}} | |||
</a> | |||
<a class="{{if .PageIsAdminResourcesSpecification}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/resources/specification"> | |||
{{.i18n.Tr "admin.resource_price"}} | |||
</a> | |||
<a class="{{if .PageIsAdminResourcesScene}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/resources/scene"> | |||
{{.i18n.Tr "admin.application_scenario"}} | |||
</a> | |||
<a class="item item-first" href="javascript:void(0);"> | |||
{{.i18n.Tr "admin.system_configuration"}} | |||
</a> | |||
<a class="{{if .PageIsAdminMonitor}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/monitor"> | |||
{{.i18n.Tr "admin.monitor"}} | |||
</a> | |||
<a class="{{if .PageIsAdminHooks}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/hooks"> | |||
{{.i18n.Tr "admin.hooks"}} | |||
</a> | |||
<a class="{{if .PageIsAdminSystemHooks}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/system-hooks"> | |||
{{.i18n.Tr "admin.systemhooks"}} | |||
</a> | |||
<a class="{{if .PageIsAdminAuthentications}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/auths"> | |||
{{.i18n.Tr "admin.authentication"}} | |||
</a> | |||
<a class="{{if .PageIsAdminConfig}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/config"> | |||
{{.i18n.Tr "admin.config"}} | |||
</a> | |||
<a class="{{if .PageIsAdminNotices}}active{{end}} item item-next" href="{{AppSubUrl}}/admin/notices"> | |||
{{.i18n.Tr "admin.notices"}} | |||
</a> | |||
</div> | |||
</div> |
@@ -0,0 +1,10 @@ | |||
{{template "base/head" .}} | |||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-resources-queue.css?v={{MD5 AppVer}}" /> | |||
<div class="admin resource"> | |||
{{template "admin/navbar" .}} | |||
<div class="ui container"> | |||
<div id="__vue-root"></div> | |||
</duv> | |||
</div> | |||
<script src="{{StaticUrlPrefix}}/js/vp-resources-queue.js?v={{MD5 AppVer}}"></script> | |||
{{template "base/footer" .}} |
@@ -0,0 +1,10 @@ | |||
{{template "base/head" .}} | |||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-resources-scene.css?v={{MD5 AppVer}}" /> | |||
<div class="admin resource"> | |||
{{template "admin/navbar" .}} | |||
<div class="ui container"> | |||
<div id="__vue-root"></div> | |||
</duv> | |||
</div> | |||
<script src="{{StaticUrlPrefix}}/js/vp-resources-scene.js?v={{MD5 AppVer}}"></script> | |||
{{template "base/footer" .}} |
@@ -0,0 +1,10 @@ | |||
{{template "base/head" .}} | |||
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-resources-specification.css?v={{MD5 AppVer}}" /> | |||
<div class="admin resource"> | |||
{{template "admin/navbar" .}} | |||
<div class="ui container"> | |||
<div id="__vue-root"></div> | |||
</duv> | |||
</div> | |||
<script src="{{StaticUrlPrefix}}/js/vp-resources-specification.js?v={{MD5 AppVer}}"></script> | |||
{{template "base/footer" .}} |
@@ -15,7 +15,7 @@ | |||
{{if .benchmarkMode}}{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}{{else}}{{.i18n.Tr "dataset.select_dataset"}}{{end}} | |||
</el-button> | |||
{{if .benchmarkMode}} | |||
<span class="tooltips" style="display: block;margin-left:11.5rem;">说明:先使用数据集功能上传模型,然后从数据集列表选模型。</span> | |||
<span class="tooltips" style="display: block;margin-left:11.5rem;">{{.i18n.Tr "dataset.benchmark_dataset_tip"}}</span> | |||
{{end}} | |||
<el-dialog title="{{.i18n.Tr "dataset.select_dataset"}}" :visible.sync="dialogVisible" width="50%"> | |||
<div v-loading="loadingDataIndex" style="position: relative;"> | |||
@@ -49,13 +49,13 @@ | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" | |||
data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压中</span> | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_stared"}}</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" | |||
data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压失败</span> | |||
data-tooltip="{{$.i18n.Tr "dataset.unzip_failed"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_failed"}}</span> | |||
</span> | |||
</div> | |||
</div> | |||
@@ -85,13 +85,13 @@ | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" | |||
data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压中</span> | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_stared"}}</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" | |||
data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压失败</span> | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_failed"}}</span> | |||
</span> | |||
</div> | |||
</div> | |||
@@ -120,13 +120,13 @@ | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" | |||
data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压中</span> | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_stared"}}</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" | |||
data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压失败</span> | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_failed"}}</span> | |||
</span> | |||
</div> | |||
</div> | |||
@@ -155,13 +155,13 @@ | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" | |||
data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压中</span> | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_stared"}}</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" | |||
data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" | |||
data-variation="mini" data-position="left center">解压失败</span> | |||
data-variation="mini" data-position="left center">{{$.i18n.Tr "dataset.unzip_failed"}}</span> | |||
</span> | |||
</div> | |||
</div> | |||
@@ -13,9 +13,9 @@ | |||
{{ end }} | |||
<i | |||
class="ri-error-warning-line" | |||
style="margin-right: 0.5rem; font-size: 16px" | |||
style="margin-right: 0.5rem; font-size: 14px" | |||
></i> | |||
<span id="gpu-nums" | |||
<span id="gpu-nums" style="font-size: 12px" | |||
>{{.i18n.Tr "repo.wait_count_start"}} | |||
{{if .QueuesDetail}} | |||
{{ $gpuQueue }} | |||
@@ -14,11 +14,11 @@ | |||
{{ end }} | |||
<i | |||
class="ri-error-warning-line" | |||
style="margin-right: 0.5rem; font-size: 16px" | |||
style="margin-right: 0.5rem; font-size: 14px" | |||
></i> | |||
<span id="gpu-nums" | |||
<span id="gpu-nums" style="font-size: 12px" | |||
>{{.ctx.i18n.Tr "repo.wait_count_start"}} | |||
{{if .type}} | |||
{{if .ctx.QueuesDetail}} | |||
{{ $gpuQueue }} | |||
{{else}} | |||
{{.ctx.WaitCount}} | |||
@@ -89,8 +89,8 @@ | |||
<div class="ui vertical masthead secondary c2net segment"> | |||
<div class="ui container"> | |||
<div class="ui center am-pt-30 am-pb-30"> | |||
<h2>智算网络</h2> | |||
<p><span class="ui text grey">人工智能算力网络推进联盟已接入11家智算中心,算力总规模1924P</p> | |||
<h2>{{.i18n.Tr "home.c2net_title"}}</h2> | |||
<p><span class="ui text grey">{{.i18n.Tr "home.c2net_desc"}}</p> | |||
</div> | |||
<div id="app" v-cloak> | |||
@@ -98,7 +98,7 @@ | |||
<div class="rotation3D-baseMap"></div> | |||
<!--旋转3D--> | |||
<div id="rotation3D" class="rotation3D"> | |||
<button class="center">中心</button> | |||
<button class="center">{{.i18n.Tr "home.c2net_center"}}</button> | |||
<div class="itemList"> | |||
<div class="rotation3D__item" :class="item.type" v-for="item in itemList"> | |||
@@ -47,7 +47,8 @@ | |||
data-uploading='{{.i18n.Tr "dropzone.uploading"}}' | |||
data-failed='{{.i18n.Tr "dropzone.failed"}}' | |||
data-repopath='{{AppSubUrl}}{{$.RepoLink}}/datasets' data-cancel='{{.i18n.Tr "cancel"}}' | |||
data-upload='{{.i18n.Tr "dataset.dataset_upload"}}'> | |||
data-upload='{{.i18n.Tr "dataset.dataset_upload"}}' | |||
data-upload-status='{{.i18n.Tr "dataset.dataset_upload_status"}}'> | |||
</div> | |||
<div id="datasetId" datasetId="{{.datasetId}}"></div> | |||
</el-form> | |||
@@ -40,7 +40,7 @@ | |||
<input type="hidden" name="benchmarkMode" value="{{.benchmarkMode}}"> | |||
{{if eq .benchmarkMode "model"}} | |||
<form class="ui form model_form" action="{{.Link}}?benchmarkMode=model" method="post"> | |||
<form id="form_id" class="ui form model_form" action="{{.Link}}?benchmarkMode=model" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<div class="required min_title inline field"> | |||
@@ -134,7 +134,7 @@ | |||
</div> | |||
</form> | |||
{{else}} | |||
<form class="ui form alogrithm_form" action="{{.Link}}?benchmarkMode=alogrithm" method="post"> | |||
<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"> | |||
@@ -178,8 +178,7 @@ | |||
</div> | |||
<div class="required unite inline min_title fields" style="width: 90%;margin-left: 5.7rem;"> | |||
<div class="required eight wide field"> | |||
<label | |||
style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label> | |||
<label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label> | |||
<select class="ui fluid selection search dropdown" id="benchmark_types_id" | |||
name="benchmark_types_id"> | |||
@@ -193,12 +192,9 @@ | |||
</select> | |||
</div> | |||
<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"> | |||
<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> | |||
</div> | |||
</div> | |||
@@ -251,6 +247,12 @@ | |||
{{template "base/footer" .}} | |||
<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) | |||
@@ -47,7 +47,7 @@ | |||
</h4> | |||
<div class="ui attached segment"> | |||
<!-- equal width --> | |||
<form class="ui form" action="{{.Link}}" method="post"> | |||
<form id="form_id" class="ui form" action="{{.Link}}" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<input type="hidden" id="ai_image_name" value="{{.image}}"> | |||
@@ -83,6 +83,10 @@ | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" Dict "ctx" $ "type" .inference_gpu_types}} | |||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_infer_gpu_tooltips" "/dataset" "/model" "/result" | Safe}}</span> | |||
</div> | |||
</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> | |||
@@ -186,8 +190,10 @@ | |||
{{end}} | |||
</select> | |||
</div> | |||
<!-- 数据集 --> | |||
{{template "custom/select_dataset_train" .}} | |||
<!-- 数据集--> | |||
<div id="select-multi-dataset"> | |||
</div> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline min_title field required"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
@@ -227,18 +233,18 @@ | |||
{{if .resource_spec_id}} | |||
{{range .inference_resource_specs}} | |||
{{if eq $.resource_spec_id .Id}} | |||
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
<option value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option> | |||
{{end}} | |||
{{end}} | |||
{{range .inference_resource_specs}} | |||
{{if ne $.resource_spec_id .Id}} | |||
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
<option value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option> | |||
{{end}} | |||
{{end}} | |||
{{else}} | |||
{{range .inference_resource_specs}} | |||
<option name="resource_spec_id" value="{{.Id}}"> | |||
GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option> | |||
{{end}} | |||
{{end}} | |||
</select> | |||
@@ -260,6 +266,12 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
let form = document.getElementById('form_id'); | |||
let createFlag = false | |||
form.onsubmit = function (e) { | |||
if(createFlag) return false | |||
createFlag = true | |||
} | |||
const RepoLink = {{.RepoLink}} | |||
let nameMap,nameList | |||
// 获取模型列表和模型名称对应的模型版本 | |||
@@ -376,17 +388,19 @@ | |||
let value = '' | |||
value += `<div class="two fields width85" id= "para${i}">` | |||
value += '<div class="field">' | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||
value +='<input type="text" class="shipping_first-name" required placeholder="' + placeholder_name+ '">' | |||
} | |||
value += '</div>' | |||
value += '<div class="field">' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||
value +='<input type="text" class="shipping_last-name" required placeholder="' + placeholder_value+ '">' | |||
} | |||
value += '</div>' | |||
value += '<span><i class="trash icon"></i></span>' | |||
@@ -268,7 +268,7 @@ | |||
<a class="item load-model-file" data-tab="four" | |||
data-gpu-flag="true" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/cloudbrain/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first" style="height:400px"> | |||
<div class="ui tab active" data-tab="first"> | |||
<div style="padding-top: 10px;"> | |||
<div class="tab_2_content"> | |||
<div class="ac-grid ac-grid-col2"> | |||
@@ -461,19 +461,7 @@ | |||
</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_dataset"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{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.train_job.run_parameter"}} | |||
@@ -504,6 +492,28 @@ | |||
</table> | |||
</div> | |||
</div> | |||
<div style="clear:both"> | |||
<table style="border:none" class="ui fixed small stackable table"> | |||
<thead> | |||
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th> | |||
</tr></thead> | |||
<tbody> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<tr> | |||
<td style="word-wrap: break-word;word-break: break-all;"> | |||
{{if eq .IsDelete true}} | |||
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
{{else}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</td> | |||
</tr> | |||
{{end}} | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -217,7 +217,9 @@ | |||
}) | |||
} | |||
validate(); | |||
let createFlag = false | |||
form.onsubmit = function (e) { | |||
if(createFlag) return false | |||
let value_task = $("input[name='display_job_name']").val() | |||
let value_image = $("input[name='image']").val() | |||
let value_data = $("input[name='attachment']").val() | |||
@@ -231,6 +233,7 @@ | |||
} | |||
let min_value_task = value_task.toLowerCase() | |||
$("input[name='display_job_name']").attr("value", min_value_task) | |||
createFlag = true | |||
document.getElementById("mask").style.display = "block" | |||
} | |||
@@ -276,13 +279,14 @@ | |||
} | |||
}) | |||
}) | |||
$('.ui.green.button').click(function () { | |||
if (!$('input[name="isBranches"]').val()) { | |||
return false | |||
} | |||
selected_value = $("#cloudbrain_benchmark_category").val() | |||
$('#store_category').attr("value", selected_value) | |||
}) | |||
</script> |
@@ -364,18 +364,7 @@ | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" | |||
id="{{.VersionName}}-duration"> | |||
{{$.duration}} | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -404,20 +393,7 @@ | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dataset"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" | |||
id="{{.VersionName}}-BenchmarkTypeName"> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
@@ -496,14 +472,46 @@ | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" | |||
id="{{.VersionName}}-duration"> | |||
{{$.duration}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
<div style="clear:both"> | |||
<table style="border:none" class="ui fixed small stackable table"> | |||
<thead> | |||
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th> | |||
</tr></thead> | |||
<tbody> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<tr> | |||
<td style="word-wrap: break-word;word-break: break-all;"> | |||
{{if eq .IsDelete true}} | |||
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
{{else}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</td> | |||
</tr> | |||
{{end}} | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="ui tab" data-tab="second{{$k}}"> | |||
@@ -75,7 +75,7 @@ | |||
</h4> | |||
<div class="ui attached segment"> | |||
<!-- equal width --> | |||
<form class="ui form" action="{{.Link}}" method="post"> | |||
<form id="form_id" class="ui form" action="{{.Link}}" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<input type="hidden" id="ai_image_name" value="{{.image}}"> | |||
@@ -115,6 +115,10 @@ | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" Dict "ctx" $ "type" .train_gpu_types}} | |||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/code" "/dataset" "/model" | Safe}}</span> | |||
</div> | |||
</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> | |||
@@ -207,13 +211,12 @@ | |||
data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} | |||
data-position="right center" data-variation="mini"></i> | |||
</span> | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a> | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
</div> | |||
<div id="select-multi-dataset"> | |||
</div> | |||
<span class="tooltips" | |||
style="margin-left: 11.5rem;margin-bottom: 1rem;">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
<span id="add_run_para" | |||
@@ -231,18 +234,18 @@ | |||
{{if .resource_spec_id}} | |||
{{range .train_resource_specs}} | |||
{{if eq $.resource_spec_id .Id}} | |||
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
<option 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}} | |||
{{end}} | |||
{{range .train_resource_specs}} | |||
{{if ne $.resource_spec_id .Id}} | |||
<option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
<option 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}} | |||
{{end}} | |||
{{else}} | |||
{{range .train_resource_specs}} | |||
<option name="resource_spec_id" value="{{.Id}}"> | |||
GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
{{$.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}} | |||
{{end}} | |||
</select> | |||
@@ -266,6 +269,12 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
let form = document.getElementById('form_id'); | |||
let createFlag = false | |||
form.onsubmit = function (e) { | |||
if(createFlag) return false | |||
createFlag = true | |||
} | |||
$('select.dropdown') | |||
.dropdown(); | |||
@@ -288,17 +297,19 @@ | |||
let value = '' | |||
value += `<div class="two fields width85" id= "para${i}">` | |||
value += '<div class="field">' | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||
value +='<input type="text" class="shipping_first-name" required placeholder="' + placeholder_name+ '">' | |||
} | |||
value += '</div>' | |||
value += '<div class="field">' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||
value +='<input type="text" class="shipping_last-name" required placeholder="' + placeholder_value + '">' | |||
} | |||
value += '</div>' | |||
value += '<span><i class="trash icon"></i></span>' | |||
@@ -286,10 +286,14 @@ | |||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
<a class="active item" | |||
data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
<a class="item" data-tab="second{{$k}}" | |||
onclick="javascript:parseInfo()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | |||
<a class="item" data-tab="third{{$k}}" | |||
onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
<a class="item log_bottom" data-tab="third{{$k}}" | |||
data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
<a class="item load-model-file" data-tab="four{{$k}}" data-gpu-flag="true" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/cloudbrain/train-job/{{.JobID}}/model_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first{{$k}}"> | |||
@@ -423,19 +427,7 @@ | |||
</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.train_dataset"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
@@ -464,6 +456,28 @@ | |||
</table> | |||
</div> | |||
</div> | |||
<div style="clear:both"> | |||
<table style="border:none" class="ui fixed small stackable table"> | |||
<thead> | |||
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th> | |||
</tr></thead> | |||
<tbody> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<tr> | |||
<td style="word-wrap: break-word;word-break: break-all;"> | |||
{{if eq .IsDelete true}} | |||
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
{{else}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</td> | |||
</tr> | |||
{{end}} | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -474,7 +488,7 @@ | |||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||
<div id="header"></div> | |||
</div> | |||
<div class="ui attached log" id="log{{.VersionName}}" | |||
<div class="ui attached log" id="log_state{{.VersionName}}" | |||
style="height: 390px !important; overflow: auto;"> | |||
<input type="hidden" id="json_value" value="{{$.result.JobStatus.AppExitDiagnostics}}"> | |||
<input type="hidden" id="ExitDiagnostics" value="{{$.ExitDiagnostics}}"> | |||
@@ -488,18 +502,41 @@ | |||
</div> | |||
<div class="ui tab" data-tab="third{{$k}}"> | |||
<div> | |||
<div> | |||
<a id="{{.VersionName}}-log-down" | |||
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}}' | |||
href="/api/v1/repos/{{$.RepoRelPath}}/cloudbrain/{{.ID}}/download_log_file"> | |||
<i class="ri-download-cloud-2-line"></i> | |||
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span> | |||
</a> | |||
</div> | |||
<div | |||
style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||
<span> | |||
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | |||
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | |||
</span> | |||
<span class="log-info-{{.VersionName}}"> | |||
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||
class="log_bottom" data-version="{{.VersionName}}"><i | |||
class="icon-to-bottom"></i></a> | |||
</span> | |||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||
<div id="header"></div> | |||
</div> | |||
<div class="ui attached log" id="log{{.VersionName}}" | |||
<div class="ui attached log log-scroll" id="log{{.VersionName}}" data-version="{{.VersionName}}" | |||
style="height: 300px !important; overflow: auto;"> | |||
<div class="ui inverted active dimmer"> | |||
<div class="ui loader"></div> | |||
</div> | |||
<input type="hidden" name="end_line" value> | |||
<input type="hidden" name="start_line" value> | |||
<pre id="log_file{{.VersionName}}"></pre> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -553,7 +590,7 @@ | |||
<div id="newmodel"> | |||
<div class="ui modal second"> | |||
<div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | |||
<h4 id="model_header">导入新模型</h4> | |||
<h4 id="model_header">{{.i18n.Tr "repo.model.manage.import_new_model"}}</h4> | |||
</div> | |||
<div class="content content-padding"> | |||
<form id="formId" method="POST" class="ui form"> | |||
@@ -563,26 +600,26 @@ | |||
<input type="hidden" name="trainTaskCreate" value="true"> | |||
<div class="required inline field"> | |||
<label>训练任务</label> | |||
<label>{{.i18n.Tr "repo.modelarts.train_job"}}</label> | |||
<input type="hidden" class="width83" id="JobId" name="JobId" readonly required> | |||
<input type="hidden" id="VersionName" name="VersionName" value="V0001"> | |||
<input style="width: 45%;" id="JobName" readonly required> | |||
</div> | |||
<div class="required inline field" id="modelname"> | |||
<label>模型名称</label> | |||
<label>{{.i18n.Tr "repo.model.manage.model_name"}}</label> | |||
<input style="width: 45%;" id="name" name="Name" required maxlength="25" | |||
onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
</div> | |||
<div class="required inline field" id="verionname"> | |||
<label>模型版本</label> | |||
<label>{{.i18n.Tr "repo.modelconvert.modelversion"}}</label> | |||
<input style="width: 45%;" id="version" name="Version" value="" readonly required maxlength="255"> | |||
</div> | |||
<div class="unite min_title inline field required"> | |||
<label>模型框架</label> | |||
<label>{{.i18n.Tr "repo.model.manage.engine"}}</label> | |||
<div class="ui dropdown selection search width70" id="choice_Engine"> | |||
<input type="hidden" id="Engine" name="Engine" required> | |||
<div class="default text">选择模型框架</div> | |||
<div class="default text">{{.i18n.Tr "repo.model.manage.select.engine"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="job-Engine"> | |||
<option class="active item" data-value="0">PyTorch</option> | |||
@@ -597,7 +634,7 @@ | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="field required"> | |||
<label for="modelSelectedFile">模型文件</label> | |||
<label for="modelSelectedFile">{{.i18n.Tr "repo.model.manage.modelfile"}}</label> | |||
</div> | |||
<div class="thirteen wide field" style="position:relative"> | |||
<input id="modelSelectedFile" type="text" readonly required onclick="showMenu();" name="modelSelectedFile" > | |||
@@ -607,12 +644,12 @@ | |||
</div> | |||
</div> | |||
<div class="inline field"> | |||
<label>模型标签</label> | |||
<label>{{.i18n.Tr "repo.model.manage.modellabel"}}</label> | |||
<input style="width: 83%;margin-left: 7px;" id="label" name="Label" maxlength="255" | |||
placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | |||
</div> | |||
<div class="inline field"> | |||
<label for="description">模型描述</label> | |||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | |||
<textarea style="width: 83%;margin-left: 7px;" 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)" | |||
@@ -870,7 +907,15 @@ | |||
function loadLog(version_name) { | |||
document.getElementById("mask").style.display = "block" | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${taskID}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||
let startLine = $('input[name=end_line]').val(); | |||
if(startLine==""){ | |||
startLine=0; | |||
} | |||
let endLine = $('input[name=end_line]').val(); | |||
if(endLine==""){ | |||
endLine = 50; | |||
} | |||
$.get(`/${userName}/${repoPath}/cloudbrain/train-job/${jobID}/get_log?endLine=${endLine}&startLine=${startLine}`, (data) => { | |||
$('input[name=end_line]').val(data.EndLine) | |||
$('input[name=start_line]').val(data.StartLine) | |||
$(`#log_file${version_name}`).text(data.Content) | |||
@@ -20,7 +20,6 @@ | |||
.wrapper { | |||
display: flex; | |||
overflow: hidden; | |||
padding: 0 1rem; | |||
} | |||
.exp { | |||
@@ -40,7 +39,8 @@ | |||
} | |||
.exp:checked+.text .btn::after { | |||
content:'{{$.i18n.Tr "org.fold"}}' | |||
content:'{{$.i18n.Tr "org.fold"}}'; | |||
color: #3291f8; | |||
} | |||
.wrapper>.text { | |||
@@ -80,7 +80,7 @@ | |||
margin-left: 20px; | |||
font-size: 14px; | |||
padding: 0 8px; | |||
background: #3F51B5; | |||
background-color: transparent; | |||
line-height: 20px; | |||
border-radius: 4px; | |||
color: #fff; | |||
@@ -89,7 +89,8 @@ | |||
} | |||
.btn::after { | |||
content:'{{$.i18n.Tr "org.unfold"}}' | |||
content:'{{$.i18n.Tr "org.unfold"}}'; | |||
color: #3291f8; | |||
} | |||
.btn::before { | |||
@@ -132,6 +133,15 @@ | |||
border: 5px solid transparent; | |||
border-top-color: #c0c4cc; | |||
} | |||
.dataset-flavor-button{ | |||
display: flex; | |||
align-items: center; | |||
padding: 0.5rem; | |||
border: 1px solid rgba(34,36,38,0.15); | |||
border-top-right-radius: 0; | |||
border-bottom-right-radius: 0; | |||
box-shadow: none | |||
} | |||
</style> | |||
<div class="repository"> | |||
{{template "repo/header" .}} | |||
@@ -142,44 +152,59 @@ | |||
<div class="item" data-private="{{.IsPrivate}}" data-decompress-state="{{.DecompressState}}"></div> | |||
{{end}} | |||
</div> | |||
<div id="dataset-base"> | |||
<div class="ui container"> | |||
<div class="ui mobile reversed stackable grid"> | |||
<div class="row"> | |||
<div class="column thirteen wide"> | |||
<h2 class="nowrap">{{.dataset.Title}}</h2> | |||
<div class="ui blue small menu compact selectcloudbrain"> | |||
<a class="active item" href="{{.RepoLink}}/datasets">{{$.i18n.Tr "dataset.current_dataset"}}</a> | |||
<a class="item" href="{{.RepoLink}}/datasets/reference_datasets">{{$.i18n.Tr "dataset.linked_dataset"}}</a> | |||
</div> | |||
<div class="column three wide right aligned"> | |||
<span style="display: flex;align-items: center;justify-content: flex-end;height: 36px;"> | |||
{{if $.IsSigned}} | |||
<div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;" | |||
@click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||
<svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" | |||
:class='{stars_active:star_active}'> | |||
<path | |||
d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"> | |||
</path> | |||
</svg> | |||
</div> | |||
<span style="line-height: 1;">${num_stars}</span> | |||
{{else}} | |||
<div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;"> | |||
<svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" | |||
:class='{stars_active:star_active}'> | |||
<path | |||
d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"> | |||
</path> | |||
</svg> | |||
</div> | |||
<span style="line-height: 1;">${num_stars}</span> | |||
{{end}} | |||
<a style="margin-left:30px;" href="{{.RepoLink}}/datasets/edit/{{.dataset.ID}}" | |||
class="ui primary basic mini {{if not $.CanWrite}} disabled {{end}} button">{{.i18n.Tr "repo.modelarts.modify"}}</a> | |||
</span> | |||
</div> | |||
<div class="row" style="align-items: center;"> | |||
<h2 class="nowrap" style="margin: 0;">{{.dataset.Title}}</h2> | |||
<!-- border-top-right-radius: 0; | |||
border-bottom-right-radius: 0; --> | |||
<div style="margin-left: 1.5rem;"> | |||
{{if $.IsSigned}} | |||
<button v-if="star_active" class="ui mini basic button" style="display: flex;align-items: center;padding: 0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;" @click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||
<i class="ri-heart-fill" style="color: #FA8C16;"></i> | |||
<span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.unfavorite"}}</span> | |||
</button> | |||
<button v-else class="ui mini basic button" style="display: flex;align-items: center;padding:0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;" @click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||
<i class="ri-heart-line" ></i> | |||
<span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.favorite"}}</span> | |||
</button> | |||
{{else}} | |||
<button v-if="star_active" class="ui mini basic button" style="display: flex;align-items: center;padding: 0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;"> | |||
<i class="ri-heart-fill" ></i> | |||
<span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.unfavorite"}}</span> | |||
</button> | |||
<button v-else class="ui mini basic button" style="display: flex;align-items: center;padding:0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;"> | |||
<i class="ri-heart-line" style="color: #FA8C16;"></i> | |||
<span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.favorite"}}</span> | |||
</button> | |||
{{end}} | |||
</div> | |||
<a class="ui mini basic button" style="display: flex;align-items: center;padding: 0.5rem;border: #888888;border-top-left-radius: 0;border-bottom-left-radius: 0;"> | |||
${num_stars} | |||
</a> | |||
<a style="margin-left:15px;padding: 0.5rem 1.5rem;" href="{{.RepoLink}}/datasets/edit/{{.dataset.ID}}" class="ui primary basic mini {{if not $.CanWrite}} disabled {{end}} button">{{.i18n.Tr "repo.modelarts.modify"}}</a> | |||
</div> | |||
{{if .dataset.Description}} | |||
<div class="row" style="padding: 0;"> | |||
<div class="wrapper"> | |||
<input id="exp1" class="exp" type="checkbox"> | |||
<div class="text"> | |||
<label class="btn" for="exp1"></label> | |||
{{.dataset.Description}} | |||
</div> | |||
</div> | |||
</div> | |||
{{end}} | |||
<div class="row" style="align-items: center;"> | |||
{{if or (.dataset.Category) (.dataset.Task) (.dataset.License)}} | |||
<div class="column thirteen wide"> | |||
<div class="column ten wide" style="padding:0"> | |||
{{if .dataset.Category}} | |||
{{$category := .dataset.Category}} | |||
<a class="ui repo-topic label topic" | |||
@@ -196,21 +221,7 @@ | |||
{{end}} | |||
</div> | |||
{{end}} | |||
</div> | |||
{{if .dataset.Description}} | |||
<div class="row" style="padding-top: 0;"> | |||
<div class=" wrapper"> | |||
<input id="exp1" class="exp" type="checkbox"> | |||
<div class="text"> | |||
<label class="btn" for="exp1"></label> | |||
{{.dataset.Description}} | |||
</div> | |||
</div> | |||
</div> | |||
{{end}} | |||
<div class="row"> | |||
<div class="column ten wide"></div> | |||
<div class="column six wide right aligned"> | |||
<div class="column six wide right aligned" style="padding:0"> | |||
<el-select v-model="datasetType" style="width: 40%;" size="small" @change="changeDatasetType"> | |||
<i slot="prefix" style="display: inline-block;color: #101010;" | |||
class="el-input__icon ri-archive-drawer-line"></i> | |||
@@ -222,7 +233,7 @@ | |||
@click="gotoUpload('{{.RepoLink}}',{{.dataset.ID}})">{{$.i18n.Tr "dataset.dataset_upload"}}</el-button> | |||
</div> | |||
</div> | |||
<div class="row"> | |||
<div class="row" style="padding-top: 0;"> | |||
<div class="ui sixteen wide column dataset"> | |||
<div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
<div class="row"> | |||
@@ -387,16 +398,27 @@ | |||
</div> | |||
</div> | |||
{{else}} | |||
<div class="ui placeholder segment bgtask-none"> | |||
<div class="ui icon header bgtask-header-pic"></div> | |||
<div class="bgtask-content-header">{{.i18n.Tr "dataset.dataset_no_create"}}</div> | |||
{{if $.CanWrite}} | |||
<a class="ui green button" href="{{.RepoLink}}/datasets/create">{{.i18n.Tr "dataset.create_new_dataset"}}</a> | |||
{{end}} | |||
<div class="bgtask-content"> | |||
<div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_explain"}}</div> | |||
<div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_instructions_for_use"}}<a | |||
href="https://git.openi.org.cn/zeizei/OpenI_Learning">{{.i18n.Tr "dataset.dataset_camp_course"}}</a></div> | |||
<div class="ui container"> | |||
<div class="ui stackable grid"> | |||
<div class="row" style="justify-content: space-between"> | |||
<div class="ui blue small menu compact selectcloudbrain"> | |||
<a class="active item" href="{{.RepoLink}}/datasets">{{$.i18n.Tr "dataset.current_dataset"}}</a> | |||
<a class="item" href="{{.RepoLink}}/datasets/reference_datasets">{{$.i18n.Tr "dataset.linked_dataset"}}</a> | |||
</div> | |||
{{if $.CanWrite}} | |||
<a class="ui green button" href="{{.RepoLink}}/datasets/create">{{$.i18n.Tr "new_dataset"}}</a> | |||
{{end}} | |||
</div> | |||
</div> | |||
<div class="ui placeholder segment bgtask-none"> | |||
<div class="ui icon header bgtask-header-pic"></div> | |||
<div class="bgtask-content-header">{{.i18n.Tr "dataset.dataset_no_create"}}</div> | |||
<div class="bgtask-content"> | |||
<div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_explain"}}</div> | |||
<div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_instructions_for_use"}}<a | |||
href="https://git.openi.org.cn/zeizei/OpenI_Learning"> {{.i18n.Tr "dataset.dataset_camp_course"}}</a></div> | |||
</div> | |||
</div> | |||
</div> | |||
{{end}} | |||
@@ -0,0 +1,8 @@ | |||
{{template "base/head" .}} | |||
<div class="repository"> | |||
{{template "repo/header" .}} | |||
<div class="reference-dataset" data-repolink="{{.RepoLink}}" data-canwrite="{{.CanWrite}}" data-is-sign="{{$.IsSigned}}" data-max-reference-num="{{.MaxReferenceDatasetNum}}" data-address="{{IsShowDataSetOfCurrentRepo $.Repository.ID}}"></div> | |||
<div id="reference-dataset"></div> | |||
</div> | |||
{{template "base/footer" .}} |
@@ -235,7 +235,8 @@ | |||
<div class="two wide column text center"> | |||
<!-- 任务计算资源 --> | |||
<span style="font-size: 12px;margin-left: 0.4rem;" | |||
class="">{{.ComputeResource}}</span> | |||
class=""> | |||
{{.ComputeResource}}</span> | |||
</div> | |||
<div class="one wide column text center"> | |||
{{if .User.Name}} | |||
@@ -66,7 +66,7 @@ | |||
</h4> | |||
<div class="ui attached segment"> | |||
<!-- equal width --> | |||
<form class="ui form" action="{{.Link}}" method="post"> | |||
<form id="form_id" class="ui form" action="{{.Link}}" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<input type="hidden" id="ai_engine_name" name="engine_name" value=""> | |||
@@ -106,6 +106,10 @@ | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" Dict "ctx" $}} | |||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/tmp/code" "/tmp/dataset" "/tmp/output" | Safe}}</span> | |||
</div> | |||
</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> | |||
@@ -160,12 +164,12 @@ | |||
<span> | |||
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||
</span> | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/train_for_c2net.py" target="_blank">查看样例</a> | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/train_for_c2net.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
</div> | |||
{{template "custom/select_dataset_train" .}} | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.grampus.gpu_dataset_path_rule"}}</span> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
@@ -214,8 +218,12 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
//let url_href = window.location.pathname.split('create')[0] | |||
//$(".ui.button").attr('href',url_href) | |||
let form = document.getElementById('form_id'); | |||
let createFlag = false | |||
form.onsubmit = function (e) { | |||
if(createFlag) return false | |||
createFlag = true | |||
} | |||
$('select.dropdown') | |||
.dropdown(); | |||
@@ -235,17 +243,19 @@ | |||
let value = '' | |||
value += `<div class="two fields width85" id= "para${i}">` | |||
value += '<div class="field">' | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||
value +='<input type="text" class="shipping_first-name" required placeholder="' + placeholder_name+ '">' | |||
} | |||
value += '</div>' | |||
value += '<div class="field">' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||
value +='<input type="text" class="shipping_last-name" required placeholder="' + placeholder_value+ '">' | |||
} | |||
value += '</div>' | |||
value += '<span><i class="trash icon"></i></span>' | |||
@@ -61,7 +61,7 @@ | |||
</h4> | |||
<div class="ui attached segment"> | |||
<!-- equal width --> | |||
<form class="ui form" action="{{.Link}}" method="post"> | |||
<form id="form_id" class="ui form" action="{{.Link}}" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<input type="hidden" id="ai_engine_name" name="engine_name" value=""> | |||
@@ -100,6 +100,10 @@ | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" Dict "ctx" $}} | |||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/cache/code" "/cache/dataset" "/cache/output" | Safe}}</span> | |||
</div> | |||
</div> | |||
<div class="required min_title inline field"> | |||
@@ -177,7 +181,7 @@ | |||
</div> | |||
{{template "custom/select_dataset_train" .}} | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.grampus.dataset_path_rule"}}</span> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
@@ -240,7 +244,12 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
let form = document.getElementById('form_id'); | |||
let createFlag = false | |||
form.onsubmit = function (e) { | |||
if(createFlag) return false | |||
createFlag = true | |||
} | |||
$('select.dropdown') | |||
.dropdown(); | |||
@@ -260,17 +269,19 @@ | |||
let value = '' | |||
value += `<div class="two fields width85" id= "para${i}">` | |||
value += '<div class="field">' | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||
value +='<input type="text" class="shipping_first-name" required placeholder="' + placeholder_name+ '">' | |||
} | |||
value += '</div>' | |||
value += '<div class="field">' | |||
if(flag){ | |||
value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||
}else{ | |||
value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||
value +='<input type="text" class="shipping_last-name" required placeholder="' + placeholder_value+ '">' | |||
} | |||
value += '</div>' | |||
value += '<span><i class="trash icon"></i></span>' | |||
@@ -419,7 +419,12 @@ | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{if eq .IsDelete true}} | |||
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
{{else}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
{{end}} | |||
</div> | |||
</td> | |||
@@ -470,11 +475,11 @@ | |||
<div class="ui tab" data-tab="second{{$k}}"> | |||
<div style="position: relative;"> | |||
<span> | |||
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | |||
<a title="{{$.i18n.Tr "repo.log_scroll_start"}}" style="position: absolute; right: -32px;cursor: pointer;" | |||
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | |||
</span> | |||
<span class="log-info-{{.VersionName}}"> | |||
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||
<a title="{{$.i18n.Tr "repo.log_scroll_end"}}" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||
class="log_bottom" data-version="{{.VersionName}}"><i | |||
class="icon-to-bottom"></i></a> | |||
</span> | |||
@@ -541,7 +546,7 @@ | |||
<div id="newmodel"> | |||
<div class="ui modal second"> | |||
<div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | |||
<h4 id="model_header">导入新模型</h4> | |||
<h4 id="model_header">{{.i18n.Tr "repo.model.manage.import_new_model"}}</h4> | |||
</div> | |||
<div class="content content-padding"> | |||
<form id="formId" method="POST" class="ui form"> | |||
@@ -551,26 +556,26 @@ | |||
<input type="hidden" name="trainTaskCreate" value="true"> | |||
<div class="required inline field"> | |||
<label>训练任务</label> | |||
<label>{{.i18n.Tr "repo.modelarts.train_job"}}</label> | |||
<input type="hidden" class="width83" id="JobId" name="JobId" readonly required> | |||
<input type="hidden" id="VersionName" name="VersionName" value="V0001"> | |||
<input style="width: 45%;" id="JobName" readonly required> | |||
</div> | |||
<div class="required inline field" id="modelname"> | |||
<label>模型名称</label> | |||
<label>{{.i18n.Tr "repo.model.manage.model_name"}}</label> | |||
<input style="width: 45%;" id="name" name="Name" required maxlength="25" | |||
onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
</div> | |||
<div class="required inline field" id="verionname"> | |||
<label>模型版本</label> | |||
<label>{{.i18n.Tr "repo.modelconvert.modelversion"}}</label> | |||
<input style="width: 45%;" id="version" name="Version" value="" readonly required maxlength="255"> | |||
</div> | |||
<div class="unite min_title inline field required"> | |||
<label>模型框架</label> | |||
<label>{{.i18n.Tr "repo.model.manage.engine"}}</label> | |||
<div class="ui dropdown selection search width70" id="choice_Engine"> | |||
<input type="hidden" id="Engine" name="Engine" required> | |||
<div class="default text">选择模型框架</div> | |||
<div class="default text">{{.i18n.Tr "repo.model.manage.select.engine"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="job-Engine"> | |||
<option class="active item" data-value="0">PyTorch</option> | |||
@@ -586,7 +591,7 @@ | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="field required"> | |||
<label for="modelSelectedFile">模型文件</label> | |||
<label for="modelSelectedFile">{{.i18n.Tr "repo.model.manage.modelfile"}}</label> | |||
</div> | |||
<div class="thirteen wide field" style="position:relative"> | |||
<input id="modelSelectedFile" type="text" readonly required onclick="showMenu();" name="modelSelectedFile" > | |||
@@ -596,12 +601,12 @@ | |||
</div> | |||
</div> | |||
<div class="inline field"> | |||
<label>模型标签</label> | |||
<label>{{.i18n.Tr "repo.model.manage.modellabel"}}</label> | |||
<input style="width: 83%;margin-left: 7px;" id="label" name="Label" maxlength="255" | |||
placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | |||
</div> | |||
<div class="inline field"> | |||
<label for="description">模型描述</label> | |||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | |||
<textarea style="width: 83%;margin-left: 7px;" 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)" | |||
@@ -138,7 +138,7 @@ | |||
{{end}} | |||
{{if .Permission.CanRead $.UnitTypeDatasets}} | |||
<a class="{{if .PageIsDataset}}active{{end}} item" href="{{.RepoLink}}/datasets"> | |||
<a class="{{if .PageIsDataset}}active{{end}} item" id="header-dataset" href="{{.RepoLink}}{{if IsShowDataSetOfCurrentRepo $.Repository.ID}}/datasets{{else}}/datasets/reference_datasets{{end}}"> | |||
<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="M20.083 15.2l1.202.721a.5.5 0 0 1 0 .858l-8.77 5.262a1 1 0 0 1-1.03 0l-8.77-5.262a.5.5 0 0 1 0-.858l1.202-.721L12 20.05l8.083-4.85zm0-4.7l1.202.721a.5.5 0 0 1 0 .858L12 17.65l-9.285-5.571a.5.5 0 0 1 0-.858l1.202-.721L12 15.35l8.083-4.85zm-7.569-9.191l8.771 5.262a.5.5 0 0 1 0 .858L12 13 2.715 7.429a.5.5 0 0 1 0-.858l8.77-5.262a1 1 0 0 1 1.03 0zM12 3.332L5.887 7 12 10.668 18.113 7 12 3.332z"/></svg> | |||
{{.i18n.Tr "datasets"}} | |||
</a> | |||
@@ -40,12 +40,13 @@ | |||
{{template "repo/header" .}} | |||
<div class="ui container"> | |||
{{template "base/alert" .}} | |||
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="1" data-repo-link="{{.RepoLink}}"></div> | |||
<h4 class="ui top attached header"> | |||
{{.i18n.Tr "repo.modelarts.train_job.new_infer"}} | |||
</h4> | |||
<div class="ui attached segment"> | |||
<!-- equal width --> | |||
<form class="ui form" action="{{.Link}}" method="post"> | |||
<form id="form_id" class="ui form" action="{{.Link}}" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||
@@ -83,6 +84,10 @@ | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" Dict "ctx" $}} | |||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.infer_dataset_path_rule" | Safe}}</span> | |||
</div> | |||
</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> | |||
@@ -191,9 +196,12 @@ | |||
{{end}} | |||
</select> | |||
</div> | |||
<!-- 数据集 --> | |||
{{template "custom/select_dataset_train" .}} | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||
<!-- 数据集 --> | |||
<div id="select-multi-dataset"> | |||
</div> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline min_title field required"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
{{if .bootFile}} | |||
@@ -269,7 +277,6 @@ | |||
<div class="ui labeled input" style="width: 5%;"> | |||
<input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | |||
</div> | |||
<span class="tooltips" style="margin-left: 11.5rem;display: block;">{{.i18n.Tr "cloudbrain.inference_output_path_rule"}}</span> | |||
</div> | |||
<!-- 表单操作 --> | |||
<div class="inline min_title field"> | |||
@@ -287,6 +294,12 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
let form = document.getElementById('form_id'); | |||
let createFlag = false | |||
form.onsubmit = function (e) { | |||
if(createFlag) return false | |||
createFlag = true | |||
} | |||
const RepoLink = {{.RepoLink}} | |||
const url_href = window.location.pathname.split('create')[0] | |||
let nameMap,nameList | |||
@@ -396,12 +409,14 @@ | |||
// 参数增加、删除、修改、保存 | |||
function Add_parameter(i){ | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
value = '<div class="two fields width85" id= "para'+ i +'">' + | |||
'<div class="field">' + | |||
'<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||
'<input type="text" name="shipping_first-name" required placeholder="' + placeholder_name+ '">' + | |||
'</div> ' + | |||
'<div class="field"> ' + | |||
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||
'<input type="text" name="shipping_last-name" required placeholder="' + placeholder_value + '">' + | |||
'</div>'+ | |||
'<span>' + | |||
'<i class="trash icon">' + | |||
@@ -217,7 +217,7 @@ td, th { | |||
<a class="item load-model-file" data-tab="third" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first" style="height:400px"> | |||
<div class="ui tab active" data-tab="first"> | |||
<div style="padding-top: 10px;"> | |||
<div class="tab_2_content"> | |||
<div class="ac-grid ac-grid-col2"> | |||
@@ -314,7 +314,7 @@ td, th { | |||
</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"> | |||
@@ -402,19 +402,7 @@ td, th { | |||
</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_dataset"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{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.train_job.run_parameter"}} | |||
@@ -445,6 +433,29 @@ td, th { | |||
</table> | |||
</div> | |||
</div> | |||
<div style="clear:both"> | |||
<table style="border:none" class="ui fixed small stackable table"> | |||
<thead> | |||
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th> | |||
</tr></thead> | |||
<tbody> | |||
{{range $m ,$n := $.datasetDownload}} | |||
<tr> | |||
<td style="word-wrap: break-word;word-break: break-all;"> | |||
{{if eq .IsDelete true}} | |||
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
{{else}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</td> | |||
</tr> | |||
{{end}} | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -123,11 +123,10 @@ | |||
}) | |||
} | |||
validate(); | |||
let createFlag = false | |||
form.onsubmit = function(e){ | |||
if(createFlag) return false | |||
let value_task = $("input[name='display_job_name']").val() | |||
let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | |||
let flag = re.test(value_task) | |||
if(!flag){ | |||
@@ -136,11 +135,10 @@ | |||
$('#messageInfo p').text(str) | |||
return false | |||
} | |||
let min_value_task = value_task.toLowerCase() | |||
$("input[name='display_job_name']").attr("value",min_value_task) | |||
document.getElementById("mask").style.display = "block" | |||
createFlag = true | |||
} | |||
// 点击按钮后遮罩层显示 | |||
@@ -350,7 +350,7 @@ | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
<span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||
<span class="ui poping up clipboard" data-position="top center" id="clipboard-btn-image" style="cursor:pointer" | |||
data-clipboard-text="{{.Image}}" | |||
data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||
data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||
@@ -432,16 +432,23 @@ | |||
<div style="clear:both"> | |||
<table style="border:none" class="ui fixed small stackable table"> | |||
<thead> | |||
<tr><th style="color: #8a8e99;font-size:12px" class="three wide center aligned">数据集文件</th> | |||
<th style="color: #8a8e99;font-size:12px"class="eleven wide">数据集下载地址</th> | |||
<th style="color: #8a8e99;font-size:12px" class="two wide center aligned">操作</th> | |||
<tr><th style="color: #8a8e99;font-size:12px" class="three wide center aligned">{{$.i18n.Tr "dataset.file"}}</th> | |||
<th style="color: #8a8e99;font-size:12px"class="eleven wide">{{$.i18n.Tr "dataset.download_url"}}</th> | |||
<th style="color: #8a8e99;font-size:12px" class="two wide center aligned">{{$.i18n.Tr "dataset.download_oper"}}</th> | |||
</tr></thead> | |||
<tbody> | |||
{{range $.datasetDownload}} | |||
<tr> | |||
<td style="word-wrap: break-word;word-break: break-all;"><a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a></td> | |||
<td style="word-wrap: break-word;word-break: break-all;"> | |||
{{if eq .IsDelete true}} | |||
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
{{else}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</td> | |||
<td style="word-wrap: break-word;word-break: break-all;">{{.DatasetDownloadLink}}</td> | |||
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{.DatasetDownloadLink}}">复制链接</a></td> | |||
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn-dataset" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{.DatasetDownloadLink}}">{{$.i18n.Tr "dataset.download_copy"}}</a></td> | |||
</tr> | |||
{{end}} | |||
</tbody> | |||
@@ -491,5 +498,4 @@ | |||
$(document).ready(function () { | |||
$('.secondary.menu .item').tab(); | |||
}); | |||
console.log({{$.datasetDownload}}) | |||
</script> |
@@ -76,10 +76,10 @@ | |||
{{range .para}} | |||
<div class="two fields"> | |||
<div class="field"> | |||
<input type="text" name="shipping_first-name" placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> | |||
<input type="text" name="shipping_first-name" placeholder="{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}"> | |||
</div> | |||
<div class="field"> | |||
<input type="text" name="shipping_last-name" placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}> | |||
<input type="text" name="shipping_last-name" placeholder="{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}"> | |||
</div> | |||
<span> | |||
<i class="trash icon"> | |||
@@ -151,12 +151,14 @@ | |||
// 参数增加、删除、修改、保存 | |||
function Add_parameter(){ | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
value = '<div class="two fields">' + | |||
'<div class="field">' + | |||
'<input type="text" name="shipping_first-name" placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||
'<input type="text" name="shipping_first-name" placeholder="' + placeholder_name+ '">' + | |||
'</div> ' + | |||
'<div class="field"> ' + | |||
'<input type="text" name="shipping_last-name" placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||
'<input type="text" name="shipping_last-name" placeholder="' + placeholder_value+ '">' + | |||
'</div>'+ | |||
'<span>' + | |||
'<i class="trash icon">' + | |||
@@ -95,7 +95,7 @@ | |||
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
<span>{{$.i18n.Tr "repo.modelarts.cluster.computing_resources"}}</span> | |||
</div> | |||
<div class="one wide column text center padding0"> | |||
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
@@ -137,7 +137,13 @@ | |||
</div> | |||
<!-- 计算资源 --> | |||
<div class="two wide column text center padding0"> | |||
<span style="font-size: 12px;">{{.ComputeResource}}</span> | |||
<span style="font-size: 12px;"> | |||
{{if eq .Cloudbrain.Type 2}} | |||
{{$.i18n.Tr "cloudbrain.resource_cluster_c2net_simple"}} | |||
{{else}} | |||
{{$.i18n.Tr "cloudbrain.resource_cluster_openi_simple"}} | |||
{{end}} | |||
{{.ComputeResource}}</span> | |||
</div> | |||
<!-- 创建者 --> | |||
<div class="one wide column text center padding0"> | |||
@@ -69,7 +69,7 @@ | |||
</h4> | |||
<div class="ui attached segment"> | |||
<!-- equal width --> | |||
<form class="ui form" action="{{.Link}}" method="post"> | |||
<form id="form_id" class="ui form" action="{{.Link}}" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||
@@ -111,11 +111,14 @@ | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" Dict "ctx" $}} | |||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;"> | |||
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i> | |||
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.train_dataset_path_rule" | Safe}}</span> | |||
</div> | |||
</div> | |||
<div class="required inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="36"> | |||
<span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||
</div> | |||
<div class="inline min_title field"> | |||
@@ -204,7 +207,7 @@ | |||
<div id="select-multi-dataset"> | |||
</div> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
@@ -309,6 +312,12 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
let form = document.getElementById('form_id'); | |||
let createFlag = false | |||
form.onsubmit = function (e) { | |||
if(createFlag) return false | |||
createFlag = true | |||
} | |||
let url_href = window.location.pathname.split('create')[0] | |||
$(".ui.button").attr('href', url_href) | |||
$('select.dropdown') | |||
@@ -321,28 +330,16 @@ | |||
case 13:return false; | |||
} | |||
}); | |||
// let sever_num = $("#trainjob_work_server_num_select .text").text() //$('#trainjob_work_server_num') | |||
// console.log("sever_num:",sever_num) | |||
// $('.add').click(function(){ | |||
// sever_num.val(parseInt(sever_num.val())+1) | |||
// if(sever_num.val()>=26){ | |||
// sever_num.val(parseInt(sever_num.val())-1) | |||
// } | |||
// }) | |||
// $('.min').click(function(){ | |||
// sever_num.val(parseInt(sever_num.val())-1) | |||
// if(sever_num.val()<=0){ | |||
// sever_num.val(parseInt(sever_num.val())+1) | |||
// } | |||
// }) | |||
// 参数增加、删除、修改、保存 | |||
function Add_parameter(i) { | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
value = '<div class="two fields width85" id= "para' + i + '">' + | |||
'<div class="field">' + | |||
'<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||
'<input type="text" name="shipping_first-name" required placeholder="' + placeholder_name+ '">' + | |||
'</div> ' + | |||
'<div class="field"> ' + | |||
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||
'<input type="text" name="shipping_last-name" required placeholder="' + placeholder_value+ '">' + | |||
'</div>' + | |||
'<span>' + | |||
'<i class="trash icon">' + | |||
@@ -274,10 +274,14 @@ | |||
{{if .CanDel}} | |||
<a class="ti-action-menu-item" onclick="deleteVersion({{.VersionName}})" | |||
<a class='ti-action-menu-item delete-show-version {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING" "RUNNING" "KILLING" "INIT"}}disabled {{end}}' | |||
id="{{.VersionName}}-delete" | |||
data-jobid="{{.JobID}}" | |||
data-repopath="{{$.RepoRelPath}}/modelarts/train-job" | |||
data-version = "{{.VersionName}}" | |||
style="color: #FF4D4F;">{{$.i18n.Tr "repo.delete"}}</a> | |||
{{else}} | |||
<a class="ti-action-menu-item disabled" onclick="deleteVersion({{.VersionName}})" | |||
<a class="ti-action-menu-item disabled" | |||
style="color: #FF4D4F;">{{$.i18n.Tr "repo.delete"}}</a> | |||
{{end}} | |||
</div> | |||
@@ -316,7 +320,7 @@ | |||
data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
<a class="item log_bottom" data-tab="second{{$k}}" | |||
data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
<a class="item metric_chart" data-tab="four{{$k}}" data-version="{{.VersionName}}">资源占用情况</a> | |||
<a class="item metric_chart" data-tab="four{{$k}}" data-version="{{.VersionName}}">{{$.i18n.Tr "cloudbrain.resource_use"}}</a> | |||
<a class="item load-model-file" data-tab="third{{$k}}" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/model_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first{{$k}}"> | |||
@@ -397,16 +401,7 @@ | |||
</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.compute_node"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.WorkServerNumber}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
@@ -445,23 +440,7 @@ | |||
</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.train_dataset"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{range $m ,$n := $.datasetList}} | |||
{{if eq $k $m}} | |||
{{range $f ,$g := $n}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
{{end}} | |||
{{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.train_job.run_parameter"}} | |||
@@ -486,10 +465,44 @@ | |||
</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.compute_node"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.WorkServerNumber}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
<div style="clear:both"> | |||
<table style="border:none" class="ui fixed small stackable table"> | |||
<thead> | |||
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th> | |||
</tr></thead> | |||
<tbody> | |||
{{range $m ,$n := $.datasetList}} | |||
{{if eq $k $m}} | |||
{{range $f ,$g := $n}} | |||
<tr> | |||
<td style="word-wrap: break-word;word-break: break-all;"> | |||
{{if eq .IsDelete true}} | |||
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
{{else}} | |||
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
{{end}} | |||
</td> | |||
</tr> | |||
{{end}} | |||
{{end}} | |||
{{end}} | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -507,11 +520,11 @@ | |||
<div | |||
style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||
<span> | |||
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | |||
<a title="{{$.i18n.Tr "repo.log_scroll_start"}}" style="position: absolute; right: -32px;cursor: pointer;" | |||
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | |||
</span> | |||
<span class="log-info-{{.VersionName}}"> | |||
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||
<a title="{{$.i18n.Tr "repo.log_scroll_end"}}" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||
class="log_bottom" data-version="{{.VersionName}}"><i | |||
class="icon-to-bottom"></i></a> | |||
</span> | |||
@@ -586,7 +599,7 @@ | |||
<div id="newmodel"> | |||
<div class="ui modal second"> | |||
<div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | |||
<h4 id="model_header">导入新模型</h4> | |||
<h4 id="model_header">{{.i18n.Tr "repo.model.manage.import_new_model"}}</h4> | |||
</div> | |||
<div class="content content-padding"> | |||
<form id="formId" method="POST" class="ui form"> | |||
@@ -597,34 +610,34 @@ | |||
<div class="two inline fields "> | |||
<div class="required ten wide field"> | |||
<label style="margin-left: -23px;">选择训练任务</label> | |||
<label style="margin-left: -23px;">{{.i18n.Tr "repo.modelarts.train_job"}}</label> | |||
<input type="hidden" class="width83" id="JobId" name="JobId" readonly required> | |||
<input class="width83" id="JobName" readonly required> | |||
</div> | |||
<div class="required six widde field"> | |||
<label>版本</label> | |||
<label>{{.i18n.Tr "repo.model.manage.version"}}</label> | |||
<input class="width70" id="VersionName" name="VersionName" readonly required> | |||
</div> | |||
</div> | |||
<div class="required inline field" id="modelname"> | |||
<label>模型名称</label> | |||
<label>{{.i18n.Tr "repo.model.manage.model_name"}}</label> | |||
<input style="width: 45%;" id="name" name="Name" required maxlength="25" | |||
onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
</div> | |||
<div class="required inline field" id="verionname"> | |||
<label>模型版本</label> | |||
<label>{{.i18n.Tr "repo.modelconvert.modelversion"}}</label> | |||
<input style="width: 45%;" id="version" name="Version" value="" readonly required maxlength="255"> | |||
</div> | |||
<div class="unite min_title inline field required"> | |||
<label>模型框架</label> | |||
<label>{{.i18n.Tr "repo.model.manage.engine"}}</label> | |||
<input type="hidden" id="Engine" name="Engine" required> | |||
<input style="width: 45%;" id="Engine_name" name="Engine_name" readonly required maxlength="255"> | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="field required"> | |||
<label for="modelSelectedFile">模型文件</label> | |||
<label for="modelSelectedFile">{{.i18n.Tr "repo.model.manage.modelfile"}}</label> | |||
</div> | |||
<div class="thirteen wide field" style="position:relative"> | |||
<input id="modelSelectedFile" type="text" readonly required onclick="showMenu();" name="modelSelectedFile" > | |||
@@ -634,12 +647,12 @@ | |||
</div> | |||
</div> | |||
<div class="inline field"> | |||
<label>模型标签</label> | |||
<label>{{.i18n.Tr "repo.model.manage.modellabel"}}</label> | |||
<input style="width: 83%;margin-left: 7px;" id="label" name="Label" maxlength="255" | |||
placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | |||
</div> | |||
<div class="inline field"> | |||
<label for="description">模型描述</label> | |||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}</label> | |||
<textarea style="width: 83%;margin-left: 7px;" 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)" | |||
@@ -896,35 +909,7 @@ | |||
$('#name').val(modelName) | |||
$('#version').val("0.0.1") | |||
} | |||
function deleteVersion(version_name) { | |||
stopBubbling(arguments.callee.caller.arguments[0]) | |||
let flag = 1; | |||
$('.ui.basic.modal').modal({ | |||
onDeny: function () { | |||
flag = false | |||
}, | |||
onApprove: function () { | |||
$.post(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/del_version`, { version_name: version_name }, (data) => { | |||
if (data.VersionListCount === 0) { | |||
location.href = `/${userName}/${repoPath}/modelarts/train-job` | |||
} else { | |||
$('#accordion' + version_name).remove() | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
flag = true | |||
}, | |||
onHidden: function () { | |||
if (flag == false) { | |||
$('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||
} | |||
} | |||
}) | |||
.modal('show') | |||
} | |||
@@ -55,6 +55,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-dataset-uuid="{{.uuid}}" data-dataset-name="{{.dataset_name}}"></div> | |||
{{template "base/alert" .}} | |||
<h4 class="ui top attached header"> | |||
{{.i18n.Tr "repo.modelarts.train_job.new"}} | |||
@@ -72,7 +73,50 @@ | |||
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||
<input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||
<input type="hidden" id="display_job_name" name="display_job_name" value="{{.display_job_name}}"> | |||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||
<div class="required min_title inline field"> | |||
<label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | |||
<div class="ui blue mini menu compact selectcloudbrain"> | |||
<a class="active item" href="javascript:void 0;" style="cursor:not-allowed;"> | |||
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | |||
{{.i18n.Tr "cloudbrain.resource_cluster_openi"}} | |||
</a> | |||
<a class="item" href="javascript:void 0;" style="cursor:not-allowed;background:rgba(0,0,0,.03);"> | |||
<svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | |||
{{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) | |||
</a> | |||
</div> | |||
</div> | |||
<div class="required inline min_title field"> | |||
<label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
<div class="ui blue mini menu compact selectcloudbrain"> | |||
<a class="item" href="javascript:void 0;" style="cursor:not-allowed;background:rgba(0,0,0,.03);"> | |||
<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="active item" href="javascript:void 0;" style="cursor:not-allowed;"> | |||
<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> | |||
</div> | |||
</div> | |||
<div style="margin-top:-5px;"> | |||
{{template "custom/wait_count_train" Dict "ctx" $}} | |||
</div> | |||
<div style="display: flex;align-items: center;margin-left: 155px;margin-top: 0.5rem;margin-bottom: 1.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.train_dataset_path_rule" | Safe}}</span> | |||
</div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<input type="hidden" style="width: 60%;" name="job_name" id="job_name" value="{{.job_name}}"> | |||
@@ -151,22 +195,10 @@ | |||
</span> | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
</div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | |||
<select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}"> | |||
{{if .dataset_name}} | |||
<option name="attachment" value="{{.uuid}}">{{.dataset_name}}</option> | |||
{{end}} | |||
{{range .attachments}} | |||
<option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option> | |||
{{if ne $.uuid .UUID}} | |||
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||
{{end}} | |||
{{end}} | |||
</select> | |||
<span class="tooltips">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||
</div> | |||
<div id="select-multi-dataset"> | |||
</div> | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline unite min_title field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
@@ -286,12 +318,14 @@ | |||
// 参数增加、删除、修改、保存 | |||
function Add_parameter(i){ | |||
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}' | |||
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}' | |||
value = '<div class="two fields width85" id= "para'+ i +'">' + | |||
'<div class="field">' + | |||
'<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||
'<input type="text" name="shipping_first-name" required placeholder="' + placeholder_name+ '">' + | |||
'</div> ' + | |||
'<div class="field"> ' + | |||
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||
'<input type="text" name="shipping_last-name" required placeholder="' + placeholder_value+ '">' + | |||
'</div>'+ | |||
'<span>' + | |||
'<i class="trash icon">' + | |||
@@ -47,13 +47,12 @@ | |||
{{if eq .MODEL_CONVERT_COUNT 0}} | |||
<div class="ui placeholder segment bgtask-none"> | |||
<div class="ui icon header bgtask-header-pic"></div> | |||
<div class="bgtask-content-header">未创建过模型转换任务</div> | |||
<div class="bgtask-content-header">{{$.i18n.Tr "repo.modelconvert.notcreate"}}</div> | |||
<div class="bgtask-content"> | |||
{{if eq .MODEL_COUNT 0}} | |||
<div class="bgtask-content-txt">请您先导入<a href="{{.RepoLink}}/modelmanage/show_model">模型</a>,然后再对其进行转换。</div> | |||
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.modelconvert.importfirst1"}}<a href="{{.RepoLink}}/modelmanage/show_model"> {{$.i18n.Tr "repo.modelconvert.importfirst2"}} </a>{{$.i18n.Tr "repo.modelconvert.importfirst3"}}</div> | |||
{{end}} | |||
<div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a | |||
href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | |||
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions1"}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning"> {{$.i18n.Tr "repo.platform_instructions2"}} </a>{{$.i18n.Tr "repo.platform_instructions3"}}</div> | |||
</div> | |||
</div> | |||
@@ -68,19 +67,19 @@ | |||
<div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
<div class="row"> | |||
<div class="three wide column padding0"> | |||
<span style="margin:0 6px">任务名称</span> | |||
<span style="margin:0 6px">{{$.i18n.Tr "repo.modelconvert.taskname"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<span>状态</span> | |||
<span>{{$.i18n.Tr "repo.modelconvert.taskstatus"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<span>原模型框架</span> | |||
<span>{{$.i18n.Tr "repo.modelconvert.srcengine"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<span>转换后格式</span> | |||
<span>{{$.i18n.Tr "repo.modelconvert.outputformat"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<span>创建时间</span> | |||
<span>{{$.i18n.Tr "repo.modelconvert.createtime"}}</span> | |||
</div> | |||
<div class="one wide column text center padding0"> | |||
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
@@ -143,10 +142,10 @@ | |||
{{if .IsCanOper}} | |||
<a id="ai-download-{{.ID}}" href="{{$.Repository.HTMLURL}}/modelmanage/download_model_convert/{{.ID}}?AllDownload=true&a=1" class='ui basic {{if eq .Status "SUCCEEDED" "COMPLETED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||
下载 | |||
{{$.i18n.Tr "repo.modelconvert.download"}} | |||
</a> | |||
{{else}} | |||
<a class="ui basic disabled button">下载</a> | |||
<a class="ui basic disabled button">{{$.i18n.Tr "repo.modelconvert.download"}}</a> | |||
{{end}} | |||
</div> | |||
</div> | |||
@@ -211,7 +210,7 @@ | |||
<input type="hidden" name="_csrf" value=""> | |||
<div class="unite min_title required inline fields" id="task_name"> | |||
<div class="three wide field right aligned"> | |||
<label for="model_convert_name">任务名称</label> | |||
<label for="model_convert_name">{{$.i18n.Tr "repo.modelconvert.taskname"}}</label> | |||
</div> | |||
<div class="twelve wide field"> | |||
<input id="model_convert_name" name="model_convert_name" required maxlength="25" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
@@ -219,10 +218,10 @@ | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="three wide field right aligned"> | |||
<label for="choice_model">模型名称</label> | |||
<label for="choice_model">{{$.i18n.Tr "repo.modelconvert.modelname"}}</label> | |||
</div> | |||
<div class="ui dropdown selection search eight wide field loading" id="choice_model" name="choice_model"> | |||
<div class="default text">选择模型</div> | |||
<div class="default text">{{$.i18n.Tr "repo.modelconvert.selectmodel"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="model-name"> | |||
</div> | |||
@@ -230,12 +229,12 @@ | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="three wide field right aligned"> | |||
<label for="choice_version">模型版本</label> | |||
<label for="choice_version">{{$.i18n.Tr "repo.modelconvert.modelversion"}}</label> | |||
</div> | |||
<div class="ui dropdown selection search eight wide field" id="choice_version"> | |||
<input type="hidden" id="ModelVersion" name="ModelVersion" required> | |||
<div class="default text">选择版本</div> | |||
<div class="default text">{{$.i18n.Tr "repo.modelconvert.selectversion"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="model-version"> | |||
@@ -244,11 +243,11 @@ | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="three wide field right aligned"> | |||
<label for="choice_file">模型文件</label> | |||
<label for="choice_file">{{$.i18n.Tr "repo.model.manage.modelfile"}}</label> | |||
</div> | |||
<div class="ui dropdown selection search eight wide field" id="choice_file"> | |||
<input type="hidden" id="ModelFile" name="ModelFile" required> | |||
<div class="default text">选择模型文件</div> | |||
<div class="default text">{{$.i18n.Tr "repo.modelconvert.selectmodelfile"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="model-file"> | |||
@@ -261,7 +260,7 @@ | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="three wide field right aligned"> | |||
<label for="SrcEngine">原模型框架</label> | |||
<label for="SrcEngine">{{$.i18n.Tr "repo.modelconvert.srcengine"}}</label> | |||
</div> | |||
<select id="SrcEngine" class="ui search dropdown eight wide field" placeholder="" style='color:#000000;' name="SrcEngine" onchange="javascript:srcEngineChanged()"> | |||
@@ -270,7 +269,7 @@ | |||
</div> | |||
<div class="unite min_title required inline fields" id="inputdataformat_div"> | |||
<div class="three wide field right aligned"> | |||
<label for="inputdataformat">输入数据格式</label> | |||
<label for="inputdataformat">{{$.i18n.Tr "repo.modelconvert.inputdataformat"}}</label> | |||
</div> | |||
<select id="inputdataformat" class="ui search dropdown eight wide field" placeholder="" style='width:50%' name="inputdataformat"> | |||
@@ -281,16 +280,16 @@ | |||
</div> | |||
<div class="unite min_title required inline fields" id="inputshape_div"> | |||
<div class="three wide field right aligned"> | |||
<label for="inputshape">输入张量形状</label> | |||
<label for="inputshape">{{$.i18n.Tr "repo.modelconvert.inputshape"}}</label> | |||
</div> | |||
<div class="eight wide field"> | |||
<input id="inputshape" name="inputshape" placeholder="如:1,1,32,32,与输入数据格式对应。" required maxlength="25"> | |||
<input id="inputshape" name="inputshape" placeholder="{{$.i18n.Tr "repo.modelconvert.inputshapetip"}}" required maxlength="25"> | |||
</div> | |||
</div> | |||
<div class="unite min_title inline fields required"> | |||
<div class="three wide field right aligned"> | |||
<label for="DestFormat">转换后格式</label> | |||
<label for="DestFormat">{{$.i18n.Tr "repo.modelconvert.outputformat"}}</label> | |||
</div> | |||
<select id="DestFormat" class="ui search dropdown eight wide field" placeholder="" style='width:50%' name="DestFormat"> | |||
@@ -300,7 +299,7 @@ | |||
</div> | |||
<div class="unite min_title inline fields"> | |||
<div class="three wide field right aligned"> | |||
<label for="NetOutputFormat">网络输出数据类型 </label> | |||
<label for="NetOutputFormat">{{$.i18n.Tr "repo.modelconvert.netoutputdata"}} </label> | |||
</div> | |||
<select id="NetOutputFormat" class="ui search dropdown eight wide field" placeholder="" style='width:50%' name="NetOutputFormat"> | |||
@@ -310,7 +309,7 @@ | |||
</div> | |||
<div class="unite min_title inline fields"> | |||
<div class="three wide field right aligned"> | |||
<label for="Description">任务描述 </label> | |||
<label for="Description">{{$.i18n.Tr "repo.modelconvert.taskdesc"}} </label> | |||
</div> | |||
<div class="twelve wide field"> | |||
<textarea id="Description" name="Description" rows="1" 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, 256)"></textarea> | |||
@@ -318,7 +317,7 @@ | |||
</div> | |||
<div class="unite min_title inline field"> | |||
<button id="submitId" name="submitId" type="button" class="ui create_train_job green button" style="position: absolute;margin-left: 150px;"> | |||
新建任务 | |||
{{$.i18n.Tr "repo.modelconvert.newtask"}} | |||
</button> | |||
</div> | |||
</div> | |||
@@ -357,7 +356,7 @@ | |||
data['name']= $('#model_convert_name').val() | |||
if(data['name']==""){ | |||
$('.ui.error.message').text("请输入任务名称。") | |||
$('.ui.error.message').text("{{.i18n.Tr "repo.modelconvert.tasknameempty"}}") | |||
$('.ui.error.message').css('display','block') | |||
$("#task_name").addClass("error") | |||
return false | |||
@@ -371,7 +370,7 @@ | |||
data['inputshape']= $('#inputshape').val(); | |||
if(inputshapeNotValid(data['inputshape'])){ | |||
$('.ui.error.message').text("格式输入错误,请输入如:1,1,32,32,与输入数据格式对应。") | |||
$('.ui.error.message').text("{{.i18n.Tr "repo.modelconvert.inputshapeerror"}}") | |||
$('.ui.error.message').css('display','block') | |||
$("#inputshape_div").addClass("error") | |||
return false | |||
@@ -411,7 +410,7 @@ | |||
.modal({ | |||
centered: false, | |||
onShow:function(){ | |||
$('#model_header').text("创建模型转换任务") | |||
$('#model_header').text("{{.i18n.Tr "repo.modelconvert.createtask"}}") | |||
$('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) | |||
createModelName() | |||
loadModelList() | |||
@@ -173,7 +173,7 @@ td, th { | |||
<h4 class="ui header" id="vertical-segment"> | |||
<div class="ui breadcrumb"> | |||
<a class="section" href="{{$.RepoLink}}/modelmanage/convert_model"> | |||
模型转换任务 | |||
{{.i18n.Tr "repo.modelconvert.taskurlname"}} | |||
</a> | |||
<div class="divider"> / </div> | |||
<div class="active section">{{.Name}}</div> | |||
@@ -243,7 +243,7 @@ td, th { | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
输入张量形状 | |||
{{$.i18n.Tr "repo.modelconvert.inputshape"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -255,7 +255,7 @@ td, th { | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
输入数据格式 | |||
{{$.i18n.Tr "repo.modelconvert.inputdataformat"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -291,7 +291,7 @@ td, th { | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
网络输出数据类型 | |||
{{$.i18n.Tr "repo.modelconvert.netoutputdata"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -311,7 +311,7 @@ td, th { | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
模型名称 | |||
{{$.i18n.Tr "repo.modelconvert.modelname"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -324,7 +324,7 @@ td, th { | |||
<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"> | |||
@@ -337,7 +337,7 @@ td, th { | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
模型文件 | |||
{{$.i18n.Tr "repo.model.manage.modelfile"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -350,7 +350,7 @@ td, th { | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
原模型框架 | |||
{{$.i18n.Tr "repo.modelconvert.srcengine"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -362,7 +362,7 @@ td, th { | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
转换后格式 | |||
{{$.i18n.Tr "repo.modelconvert.outputformat"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -439,10 +439,10 @@ td, th { | |||
<div class="ui tab" data-tab="five"> | |||
<div style="position: relative;"> | |||
<span> | |||
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" class="log_top" data-version="V0001"><i class="icon-to-top"></i></a> | |||
<a title="{{$.i18n.Tr "repo.log_scroll_start"}}" style="position: absolute; right: -32px;cursor: pointer;" class="log_top" data-version="V0001"><i class="icon-to-top"></i></a> | |||
</span> | |||
<span> | |||
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" class="log_bottom" data-version="V0001"><i class="icon-to-bottom"></i></a> | |||
<a title="{{$.i18n.Tr "repo.log_scroll_end"}}" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" class="log_bottom" data-version="V0001"><i class="icon-to-bottom"></i></a> | |||
</span> | |||
<div id="log_npu_message" class="ui message message" style="display: none;"> | |||
<div id="log_npu_header"></div> | |||
@@ -64,17 +64,16 @@ | |||
{{if eq $.MODEL_COUNT 0}} | |||
<div class="ui placeholder segment bgtask-none"> | |||
<div class="ui icon header bgtask-header-pic"></div> | |||
<div class="bgtask-content-header">未创建过模型</div> | |||
<div class="bgtask-content-header">{{$.i18n.Tr "repo.model.manage.notcreatemodel"}}</div> | |||
<div class="bgtask-content"> | |||
{{if $.RepoIsEmpty}} | |||
<div class="bgtask-content-txt">代码版本:您还没有初始化代码仓库,请先<a href="{{.RepoLink}}">创建代码版本;</a></div> | |||
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.model.manage.init1"}}<a href="{{.RepoLink}}">{{$.i18n.Tr "repo.model.manage.init2"}}</a></div> | |||
{{end}} | |||
{{if eq $.TRAIN_COUNT 0}} | |||
<div class="bgtask-content-txt">训练任务:您还没创建过训练任务,请先创建<a | |||
href="{{.RepoLink}}/modelarts/train-job">训练任务</a>。</div> | |||
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.model.manage.createtrainjob_tip"}}<a | |||
href="{{.RepoLink}}/modelarts/train-job"> {{$.i18n.Tr "repo.model.manage.createtrainjob"}}</a></div> | |||
{{end}} | |||
<div class="bgtask-content-txt">使用说明:可以参考启智AI协作平台<a | |||
href="https://git.openi.org.cn/zeizei/OpenI_Learning">小白训练营课程。</a></div> | |||
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions1"}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning"> {{$.i18n.Tr "repo.platform_instructions2"}} </a>{{$.i18n.Tr "repo.platform_instructions3"}}</div> | |||
</div> | |||
<div style="display: none;"> | |||
@@ -108,11 +107,11 @@ | |||
<div id="deletemodel"> | |||
<div class="ui basic modal first"> | |||
<div class="ui icon header"> | |||
<i class="trash icon"></i> 删除模型 | |||
<i class="trash icon"></i> {{.i18n.Tr "repo.model.manage.delete"}} | |||
</div> | |||
<div class="content"> | |||
<p>你确认删除该模型么?此模型一旦删除不可恢复。</p> | |||
<p>{{.i18n.Tr "repo.model.manage.delete_confirm"}}</p> | |||
</div> | |||
<div class="actions"> | |||
<div class="ui red basic inverted cancel button"> | |||
@@ -139,21 +138,21 @@ | |||
<input type="hidden" name="_csrf" value=""> | |||
<div class="inline fields"> | |||
<div class="required two wide field right aligned"> | |||
<label for="JobId">选择训练任务</label> | |||
<label for="JobId">{{.i18n.Tr "repo.model.manage.select.trainjob"}}</label> | |||
</div> | |||
<div class="required thirteen wide inline field"> | |||
<div class="ui dropdown selection search loading" id="choice_model"> | |||
<input type="hidden" id="JobId" name="JobId" required> | |||
<div class="default text">选择训练任务</div> | |||
<div class="default text">{{.i18n.Tr "repo.model.manage.select.trainjob"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="job-name"> | |||
</div> | |||
</div> | |||
<label for="VersionName">版本</label> | |||
<label for="VersionName">{{.i18n.Tr "repo.model.manage.version"}}</label> | |||
<span> </span> | |||
<div class="ui dropdown selection search" id="choice_version"> | |||
<input type="hidden" id="VersionName" name="VersionName" required> | |||
<div class="default text">选择版本</div> | |||
<div class="default text">{{.i18n.Tr "repo.model.manage.select.version"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="job-version"> | |||
@@ -163,7 +162,7 @@ | |||
</div> | |||
<div class="required inline fields" id="modelname"> | |||
<div class="two wide field right aligned"> | |||
<label for="Name">模型名称</label> | |||
<label for="Name">{{.i18n.Tr "repo.model.manage.model_name"}}</label> | |||
</div> | |||
<div class="eight wide field"> | |||
<input id="name" name="Name" required maxlength="25" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
@@ -171,7 +170,7 @@ | |||
</div> | |||
<div class="required inline fields" id="verionname"> | |||
<div class="two wide field right aligned"> | |||
<label for="Version">模型版本</label> | |||
<label for="Version">{{.i18n.Tr "repo.model.manage.version"}}</label> | |||
</div> | |||
<div class="eight wide field"> | |||
<input id="version" name="Version" value="" readonly required maxlength="255"> | |||
@@ -180,11 +179,11 @@ | |||
<div class="unite min_title inline fields required"> | |||
<div class="two wide field right aligned"> | |||
<label for="Engine">模型框架</label> | |||
<label for="Engine">{{.i18n.Tr "repo.model.manage.engine"}}</label> | |||
</div> | |||
<div class="ui ten wide field dropdown selection search" id="choice_Engine"> | |||
<input type="hidden" id="Engine" name="Engine" required> | |||
<div class="default text newtext">选择模型框架</div> | |||
<div class="default text newtext">{{.i18n.Tr "repo.model.manage.select.engine"}}</div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="job-Engine"> | |||
@@ -195,7 +194,7 @@ | |||
<div class="unite min_title inline fields required"> | |||
<div class="two wide field right aligned"> | |||
<label for="modelSelectedFile">模型文件</label> | |||
<label for="modelSelectedFile">{{.i18n.Tr "repo.model.manage.modelfile"}}</label> | |||
</div> | |||
<div class="thirteen wide field" style="position:relative"> | |||
<input id="modelSelectedFile" type="text" readonly required onclick="showMenu();" name="modelSelectedFile" > | |||
@@ -207,7 +206,7 @@ | |||
<div class="inline fields"> | |||
<div class="two wide field right aligned"> | |||
<label for="Label">模型标签  </label> | |||
<label for="Label">{{.i18n.Tr "repo.model.manage.modellabel"}}  </label> | |||
</div> | |||
<div class="thirteen wide field"> | |||
<input id="label" name="Label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | |||
@@ -215,7 +214,7 @@ | |||
</div> | |||
<div class="inline fields"> | |||
<div class="two wide field right aligned"> | |||
<label for="description">模型描述  </label> | |||
<label for="description">{{.i18n.Tr "repo.model.manage.modeldesc"}}  </label> | |||
</div> | |||
<div class="thirteen wide field"> | |||
<textarea id="Description" name="Description" rows="3" | |||
@@ -331,7 +330,7 @@ | |||
.modal({ | |||
centered: false, | |||
onShow: function () { | |||
$('#model_header').text("导入新模型") | |||
$('#model_header').text({{.i18n.Tr "repo.model.manage.import_new_model"}}) | |||
$('input[name="Version"]').addClass('model_disabled') | |||
$('.ui.dimmer').css({ "background-color": "rgb(136, 136, 136,0.7)" }) | |||
$("#job-name").empty() | |||
@@ -86,7 +86,7 @@ | |||
</div> | |||
<div class="ui tab active" data-tab="first"> | |||
<div class="half-table"> | |||
<span class="model_header_text">基本信息</span> | |||
<span class="model_header_text">{{$.i18n.Tr "repo.model.manage.baseinfo"}}</span> | |||
<table class="tableStyle" style="margin-top:20px;"> | |||
<tbody> | |||
<tr> | |||
@@ -125,7 +125,7 @@ | |||
</td> | |||
</tr> | |||
<tr> | |||
<td class="ti-text-form-label text-width80">训练任务</td> | |||
<td class="ti-text-form-label text-width80">{{$.i18n.Tr "repo.modelarts.train_job"}}</td> | |||
<td class="ti-text-form-content word-elipsis"> | |||
<a id="DisplayJobNameHref" class="title" style="font-size: 14px;" target="_blank"> | |||
<span id="DisplayJobName" class="fitted" style="width: 90%;vertical-align: middle;"></span> | |||
@@ -18,7 +18,7 @@ | |||
<label | |||
class="el-form-item__label" | |||
style="width: 140px; position: absolute; left: -140px" | |||
>上传状态:</label | |||
>{{ upload_status }}:</label | |||
> | |||
<div v-for="(item, index) in uploadFiles" class="datast-upload-progress"> | |||
<span class="dataset-name nowrap" :title="item.name">{{ | |||
@@ -103,6 +103,7 @@ export default { | |||
btnFlag: false, | |||
cancel: "", | |||
upload: "", | |||
upload_status: "", | |||
uploadFiles: [], | |||
uploadFilesAddId: [], | |||
// allUploadFiles: [], | |||
@@ -119,6 +120,7 @@ export default { | |||
this.repoPath = this.dropzoneParams.data("repopath"); | |||
this.cancel = this.dropzoneParams.data("cancel"); | |||
this.upload = this.dropzoneParams.data("upload"); | |||
this.upload_status = this.dropzoneParams.data("upload-status"); | |||
let previewTemplate = ` | |||
<div class="dz-preview dz-file-preview"> | |||
<div class="dz-image"> | |||
@@ -14,7 +14,7 @@ | |||
> | |||
<el-table-column | |||
prop="Name" | |||
label="模型名称" | |||
:label="i18n.model_name" | |||
align="left" | |||
min-width="18%" | |||
> | |||
@@ -28,7 +28,7 @@ | |||
</el-table-column> | |||
<el-table-column | |||
prop="Version" | |||
label="版本" | |||
:label="i18n.model_version" | |||
align="center" | |||
min-width="6.5%" | |||
> | |||
@@ -39,7 +39,7 @@ | |||
<el-table-column | |||
prop="VersionCount" | |||
label="版本数" | |||
:label="i18n.model_version_num" | |||
align="center" | |||
min-width="7.5%" | |||
> | |||
@@ -50,7 +50,7 @@ | |||
<el-table-column | |||
prop="Size" | |||
label="模型大小" | |||
:label="i18n.model_size" | |||
align="center" | |||
min-width="10.5%" | |||
> | |||
@@ -60,7 +60,7 @@ | |||
</el-table-column> | |||
<el-table-column | |||
prop="EngineName" | |||
label="模型框架" | |||
:label="i18n.model_egine" | |||
align="center" | |||
min-width="8.5%" | |||
> | |||
@@ -70,7 +70,7 @@ | |||
</el-table-column> | |||
<el-table-column | |||
prop="ComputeResource" | |||
label="计算资源" | |||
:label="i18n.model_compute_resource" | |||
align="center" | |||
min-width="10.5%" | |||
> | |||
@@ -80,7 +80,7 @@ | |||
</el-table-column> | |||
<el-table-column | |||
prop="CreatedUnix" | |||
label="创建时间" | |||
:label="i18n.model_create_time" | |||
align="center" | |||
min-width="13.75%" | |||
> | |||
@@ -90,7 +90,7 @@ | |||
</el-table-column> | |||
<el-table-column | |||
prop="UserName" | |||
label="创建者" | |||
:label="i18n.model_creator" | |||
align="center" | |||
min-width="6.75%" | |||
> | |||
@@ -101,12 +101,12 @@ | |||
</template> | |||
</el-table-column> | |||
<el-table-column label="操作" min-width="18%" align="center"> | |||
<el-table-column :label="i18n.model_operation" min-width="18%" align="center"> | |||
<template slot-scope="scope"> | |||
<div class="space-around"> | |||
<a :style="{visibility:!scope.row.Children ? 'visible':'hidden'}" :class="{'disabled':!scope.row.IsCanOper}" @click="showcreateVue(scope.row.Name,scope.row.Version,scope.row.Label)">创建新版本</a> | |||
<a :href="loadhref+scope.row.ID" :class="{'disabled':!scope.row.IsCanOper}">下载</a> | |||
<a :class="{'disabled':!scope.row.IsCanDelete}" @click="deleteModel(scope.row.ID,scope.row.cName,scope.row.rowKey)">删除</a> | |||
<a :style="{visibility:!scope.row.Children ? 'visible':'hidden'}" :class="{'disabled':!scope.row.IsCanOper}" @click="showcreateVue(scope.row.Name,scope.row.Version,scope.row.Label)">{{i18n.model_create_new_ver}}</a> | |||
<a :href="loadhref+scope.row.ID" :class="{'disabled':!scope.row.IsCanOper}">{{i18n.model_download}}</a> | |||
<a :class="{'disabled':!scope.row.IsCanDelete}" @click="deleteModel(scope.row.ID,scope.row.cName,scope.row.rowKey)">{{i18n.model_delete}}</a> | |||
</div> | |||
</template> | |||
@@ -141,7 +141,7 @@ export default { | |||
}, | |||
data() { | |||
return { | |||
i18n: {}, | |||
currentPage:1, | |||
pageSize:10, | |||
totalNum:0, | |||
@@ -197,11 +197,12 @@ export default { | |||
this.getModelList() | |||
}, | |||
showcreateVue(name,version,label){ | |||
let title= this.i18n.model_create_version_title; | |||
$('.ui.modal.second') | |||
.modal({ | |||
centered: false, | |||
onShow:function(){ | |||
$('#model_header').text("创建模型新版本") | |||
$('#model_header').text(title) | |||
$('input[name="Name"]').addClass('model_disabled') | |||
$('input[name="Name"]').attr('readonly','readonly') | |||
$('input[name="modelSelectedFile"]').attr('readonly','readonly') | |||
@@ -451,7 +452,13 @@ export default { | |||
this.url_create_newVersion = this.url + 'create_model' | |||
this.url_create_newModel = this.url + 'create_new_model' | |||
}, | |||
created() { | |||
if (document.documentElement.attributes["lang"].nodeValue == "en-US") { | |||
this.i18n = this.$locale.US; | |||
} else { | |||
this.i18n = this.$locale.CN; | |||
} | |||
}, | |||
beforeDestroy() { // 实例销毁之前对点击事件进行解绑 | |||
this.submitId.removeEventListener('click', this.submit); | |||
} | |||
@@ -0,0 +1,747 @@ | |||
<template> | |||
<div> | |||
<template v-if="showFlag"> | |||
<div v-loading="loadingLinkPage"> | |||
<div class="ui container"> | |||
<div class="ui mobile reversed stackable grid"> | |||
<div class="row" style="justify-content: space-between"> | |||
<div class="ui blue small menu compact selectcloudbrain"> | |||
<a class="item" :href="`${repoLink}/datasets`">{{ | |||
i18n.current_dataset | |||
}}</a> | |||
<a | |||
class="active item" | |||
:href="`${repoLink}/datasets/reference_datasets`" | |||
>{{ i18n.linked_datasets }}</a | |||
> | |||
</div> | |||
<button | |||
style="margin-right: 2rem" | |||
class="ui green button" | |||
:class="{ disabled: !canWrite }" | |||
@click="openDataset()" | |||
> | |||
{{ i18n.linked_datasets }} | |||
</button> | |||
</div> | |||
<div class="row"> | |||
<div class="ui two cards" style="width: 100%"> | |||
<div | |||
class="ui card refer-dataset-card" | |||
v-for="(item, index) in datasetList" | |||
:key="index" | |||
@click="gotoDataset(item)" | |||
> | |||
<div class="content" style="border-bottom: none"> | |||
<div class="refer-dataset-card-content"> | |||
<div class="refer-dataset-card-title"> | |||
<span | |||
:title="item.Title" | |||
class="nowrap" | |||
style="display: inline-block; max-width: 90%" | |||
>{{ item.Title }}</span | |||
><img | |||
v-if="item.Recommend" | |||
src="/img/jian.svg" | |||
style="margin-left: 0.5rem" | |||
/> | |||
</div> | |||
<template v-if="item.IsStaring"> | |||
<div style="display: flex"> | |||
<button | |||
class="ui mini basic button dataset-card-flavor" | |||
@click.stop="postStar(item, isSigned)" | |||
> | |||
<i class="ri-heart-fill" style="color: #fa8c16"></i> | |||
<span style="margin-left: 0.3rem">{{ | |||
i18n.unfavorite | |||
}}</span> | |||
</button> | |||
<a class="ui mini basic button card-flavor-num"> | |||
{{ item.NumStars }} | |||
</a> | |||
</div> | |||
</template> | |||
<template v-else> | |||
<div style="display: flex"> | |||
<button | |||
class="ui mini basic button dataset-card-flavor" | |||
@click.stop="postStar(item, isSigned)" | |||
> | |||
<i class="ri-heart-line"></i> | |||
<span style="margin-left: 0.3rem">{{ | |||
i18n.favorite | |||
}}</span> | |||
</button> | |||
<a class="ui mini basic button card-flavor-num"> | |||
{{ item.NumStars }} | |||
</a> | |||
</div> | |||
</template> | |||
</div> | |||
<div style="font-size: 12px; margin-top: 5px"> | |||
<a | |||
v-if="item.Category" | |||
:href="'/explore/datasets?category=' + item.Category" | |||
class="ui repo-topic label topic" | |||
@click.stop | |||
>{{ i18n[item.Category] || item.Category }}</a | |||
> | |||
<a | |||
v-if="item.Task" | |||
:href="'/explore/datasets?task=' + item.Task" | |||
class="ui repo-topic label topic" | |||
@click.stop | |||
>{{ i18n[item.Task] || item.Task }}</a | |||
> | |||
<a | |||
v-if="item.License" | |||
:href="'/explore/datasets?license=' + item.License" | |||
class="ui repo-topic label topic" | |||
@click.stop | |||
>{{ item.License }}</a | |||
> | |||
</div> | |||
<div class="description card-flavor-desc"> | |||
<p>{{ item.Description }}</p> | |||
</div> | |||
</div> | |||
<div | |||
class="extra content" | |||
style="border-top: none !important" | |||
> | |||
<div style="display: flex; align-items: center"> | |||
<a | |||
:href="'/' + item.Repo.OwnerName" | |||
:title="item.Repo.OwnerName" | |||
@click.stop | |||
> | |||
<img | |||
class="ui avatar image" | |||
style="width: 22px; height: 22px" | |||
:src="'/user/avatar/' + item.Repo.OwnerName + '/-1'" | |||
/> | |||
</a> | |||
<span | |||
style=" | |||
color: #999999; | |||
font-size: 12px; | |||
margin-left: 0.5rem; | |||
" | |||
>{{ item.CreatedUnix | transformTimestamp }}</span | |||
> | |||
<span | |||
style=" | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
margin: 0 1rem; | |||
" | |||
:title="i18n.citations" | |||
> | |||
<i class="ri-link"></i> | |||
<span | |||
style=" | |||
color: #101010; | |||
font-size: 12px; | |||
margin-left: 0.2rem; | |||
" | |||
>{{ item.UseCount }}</span | |||
> | |||
</span> | |||
<span | |||
style="display: flex; align-items: center; flex: 1" | |||
:title="i18n.downloads" | |||
> | |||
<i class="ri-download-line"></i> | |||
<span | |||
style=" | |||
color: #101010; | |||
font-size: 12px; | |||
margin-left: 0.2rem; | |||
" | |||
>{{ item.DownloadTimes }}</span | |||
> | |||
</span> | |||
<button | |||
class="ui mini button" | |||
:class="{ disabled1: !canWrite }" | |||
@click.stop=" | |||
cancelReferData(item.ID, item.Title, canWrite) | |||
" | |||
> | |||
{{ i18n.disassociate }} | |||
</button> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<template v-else> | |||
<div class="ui container"> | |||
<div class="ui mobile reversed stackable grid"> | |||
<div class="row" style="justify-content: space-between"> | |||
<div class="ui blue small menu compact selectcloudbrain"> | |||
<a class="item" :href="`${repoLink}/datasets`">{{ | |||
i18n.current_dataset | |||
}}</a> | |||
<a | |||
class="active item" | |||
:href="`${repoLink}/datasets/reference_datasets`" | |||
>{{ i18n.linked_datasets }}</a | |||
> | |||
</div> | |||
<button class="ui green button" @click="openDataset()"> | |||
{{ i18n.linked_datasets }} | |||
</button> | |||
</div> | |||
</div> | |||
<div class="ui placeholder segment bgtask-none"> | |||
<div class="ui icon header bgtask-header-pic"></div> | |||
<div class="bgtask-content-header">{{ i18n.not_link_dataset }}</div> | |||
<div class="bgtask-content"> | |||
<div class="bgtask-content-txt"> | |||
{{ i18n.no_link_dataset_tips1 }} | |||
</div> | |||
<div class="bgtask-content-txt"> | |||
{{ i18n.dataset_instructions_for_use | |||
}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">{{ | |||
i18n.dataset_camp_course | |||
}}</a> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<el-dialog | |||
:title="i18n.linked_datasets" | |||
:visible.sync="dialogVisible" | |||
:width="dialogWidth" | |||
@closed="refreshData" | |||
> | |||
<div class="ui icon input dataset-search-vue"> | |||
<i | |||
class="search icon" | |||
style="cursor: pointer; pointer-events: auto" | |||
@click="searchName" | |||
></i> | |||
<input | |||
type="text" | |||
:placeholder="i18n.search_dataset" | |||
v-model="search" | |||
@keydown.enter.stop.prevent="searchName" | |||
/> | |||
</div> | |||
<el-row> | |||
<el-col | |||
:span="17" | |||
style=" | |||
padding-right: 1rem; | |||
border-right: 1px solid #f5f5f6; | |||
position: relative; | |||
" | |||
> | |||
<el-tabs v-model="activeName"> | |||
<el-tab-pane :label="i18n.public_dataset" name="first"> | |||
<el-row v-loading="loadingPublicPage" style="min-height: 50px"> | |||
<el-checkbox-group | |||
v-model="checkList" | |||
style="font-size: 14px; line-height: 1" | |||
> | |||
<div | |||
v-for="(item, index) in publicDatasetList" | |||
:key="index" | |||
class="select-data-wrap" | |||
> | |||
<div class="dataset-header-vue"> | |||
<el-checkbox | |||
:label="item.ID" | |||
@change="(checked) => changeCheckbox(checked, item)" | |||
:title="item.Title" | |||
class="select-data-title" | |||
style="display: flex; align-items: end" | |||
><span class="ref-data-title"> | |||
<span | |||
style="overflow: hidden; text-overflow: ellipsis" | |||
> | |||
{{ item.Title }} | |||
</span> | |||
<img | |||
v-if="item.Recommend" | |||
src="/img/jian.svg" | |||
style="margin-left: 0.5rem" | |||
/> </span | |||
></el-checkbox> | |||
<a | |||
class="select-data-title select-data-href" | |||
:href="`/${item.Repo.OwnerName}/${item.Repo.Name}/datasets`" | |||
:title="`${item.Repo.OwnerName}/${item.Repo.Alias}`" | |||
style="font-size: 12px" | |||
target="_blank" | |||
>{{ item.Repo.OwnerName }}/{{ item.Repo.Alias }}</a | |||
> | |||
</div> | |||
<div class="data-multiple-wrap" :title="item.Description"> | |||
{{ item.Description }} | |||
</div> | |||
</div> | |||
</el-checkbox-group> | |||
</el-row> | |||
<div | |||
class="ui container" | |||
style="margin-top: 25px; text-align: center" | |||
> | |||
<el-pagination | |||
background | |||
@current-change="currentChange" | |||
:current-page="currentPage" | |||
:page-size="5" | |||
layout="total, prev, pager, next" | |||
:total="totalNum" | |||
> | |||
</el-pagination> | |||
</div> | |||
</el-tab-pane> | |||
</el-tabs> | |||
</el-col> | |||
<el-col | |||
:span="7" | |||
style=" | |||
display: flex; | |||
flex-direction: column; | |||
height: 100%; | |||
right: 0; | |||
position: absolute; | |||
padding: 0 1.5rem; | |||
" | |||
> | |||
<div | |||
style=" | |||
font-size: 14px; | |||
height: 40px; | |||
text-align: left; | |||
color: #0066ff; | |||
line-height: 40px; | |||
" | |||
> | |||
{{ i18n.selected_data_file }} | |||
</div> | |||
<div | |||
style=" | |||
flex: 1; | |||
margin-top: 1.5rem; | |||
margin-bottom: 1rem; | |||
overflow-y: auto; | |||
" | |||
> | |||
<el-checkbox | |||
v-for="(item, index) in selectDatasetArray" | |||
:key="index" | |||
:label="item.ID" | |||
:title="item.Title" | |||
:value="item.isChecked" | |||
@change="(checked) => changeCheckSelected(checked, item)" | |||
style="display: flex; margin: 0.5rem 0" | |||
><span class="select-data-right">{{ | |||
item.Title | |||
}}</span></el-checkbox | |||
> | |||
</div> | |||
<div style="text-align: end"> | |||
<el-button | |||
@click.native="confirmDataset" | |||
size="small" | |||
style=" | |||
background: #389e0d; | |||
color: #fff; | |||
border: 1px solid #389e0d; | |||
" | |||
>{{ i18n.sure }}</el-button | |||
> | |||
</div> | |||
</el-col> | |||
</el-row> | |||
</el-dialog> | |||
</div> | |||
</template> | |||
<script> | |||
const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config; | |||
export default { | |||
components: {}, | |||
data() { | |||
return { | |||
dialogWidth: "65%", | |||
dialogVisible: false, | |||
activeName: "first", | |||
repoLink: "", | |||
datasetList: [], | |||
test: false, | |||
checkList: [], | |||
publicDatasetList: [], | |||
showFlag: true, | |||
search: "", | |||
selectDatasetArray: [], | |||
paramsPublics: { page: 1, q: "" }, | |||
i18n: {}, | |||
totalNum: 0, | |||
currentPage: 1, | |||
loadingLinkPage: false, | |||
loadingPublicPage: false, | |||
canWrite: true, | |||
isSigned: false, | |||
maxReferenceNum: 20, | |||
isCurrentUrl: true, | |||
}; | |||
}, | |||
methods: { | |||
openDataset() { | |||
this.checkList = this.datasetList.map((item) => { | |||
this.selectDatasetArray.push({ | |||
ID: item.ID, | |||
Title: item.Title, | |||
isChecked: true, | |||
}); | |||
return item.ID; | |||
}); | |||
this.dialogVisible = true; | |||
this.getDatasetList(); | |||
}, | |||
refreshData() { | |||
this.checkList = []; | |||
this.selectDatasetArray = []; | |||
}, | |||
gotoDataset(item) { | |||
window.open(`/${item.Repo.OwnerName}/${item.Repo.Name}/datasets`); | |||
}, | |||
currentChange(page) { | |||
this.paramsPublics.page = page; | |||
this.getDatasetList(); | |||
}, | |||
searchName() { | |||
this.paramsPublics.q = this.search; | |||
this.paramsPublics.page = 1; | |||
this.getDatasetList(); | |||
}, | |||
cancelReferData(id, name, canWrite) { | |||
if (!canWrite) { | |||
return; | |||
} | |||
let url = `${this.repoLink}/datasets/reference_datasets/${id}`; | |||
this.$axios | |||
.delete(url) | |||
.then((res) => { | |||
if (res.data.Code === 0) { | |||
this.$message.success(this.i18n.cancel_link_dataset.format(name)); | |||
let index = this.datasetList.findIndex((item) => { | |||
return item.ID === id; | |||
}); | |||
this.datasetList.splice(index, 1); | |||
if (this.datasetList.length === 0) { | |||
this.showFlag = false; | |||
} | |||
} else { | |||
this.$message.error(res.data.Message); | |||
} | |||
}) | |||
.catch((err) => { | |||
this.$message.error(this.i18n.dataset_link_failed); | |||
console.log(err); | |||
}); | |||
}, | |||
confirmDataset() { | |||
this.submitReferDataset(); | |||
this.dialogVisible = false; | |||
}, | |||
changeCheckbox(checked, item) { | |||
if (this.checkList.length > this.maxReferenceNum) { | |||
this.checkList.pop(); | |||
this.$message.error( | |||
this.i18n.dataset_over_nums.format(this.maxReferenceNum) | |||
); | |||
return; | |||
} | |||
if (this.checkList.length === this.maxReferenceNum && !checked) { | |||
this.$message.error( | |||
this.i18n.dataset_over_nums.format(this.maxReferenceNum) | |||
); | |||
return; | |||
} | |||
if (checked) { | |||
this.selectDatasetArray.push({ | |||
ID: item.ID, | |||
Title: item.Title, | |||
isChecked: true, | |||
}); | |||
} else { | |||
let index = this.selectDatasetArray.findIndex((element) => { | |||
return element.ID === item.ID; | |||
}); | |||
this.selectDatasetArray.splice(index, 1); | |||
} | |||
}, | |||
changeCheckSelected(checked, item) { | |||
let index = this.selectDatasetArray.findIndex((element) => { | |||
return element.ID === item.ID; | |||
}); | |||
this.selectDatasetArray.splice(index, 1); | |||
this.checkList.splice(index, 1); | |||
}, | |||
postStar(item, isSigned) { | |||
if (!isSigned) { | |||
return; | |||
} | |||
if (item.IsStaring) { | |||
let url = `${this.repoLink}/datasets/${item.ID}/unstar`; | |||
this.$axios.put(url).then((res) => { | |||
if (res.data.Code === 0) { | |||
this.datasetList.forEach((element, i) => { | |||
if (element.ID === item.ID) { | |||
this.datasetList[i].NumStars -= 1; | |||
this.datasetList[i].IsStaring = !this.datasetList[i].IsStaring; | |||
} | |||
}); | |||
} | |||
}); | |||
} else { | |||
let url = `${this.repoLink}/datasets/${item.ID}/star`; | |||
this.$axios.put(url).then((res) => { | |||
if (res.data.Code === 0) { | |||
this.datasetList.forEach((element, i) => { | |||
if (element.ID === item.ID) { | |||
this.datasetList[i].NumStars += 1; | |||
this.datasetList[i].IsStaring = !this.datasetList[i].IsStaring; | |||
} | |||
}); | |||
} | |||
}); | |||
} | |||
}, | |||
getSelectDatasetList() { | |||
this.loadingLinkPage = true; | |||
let url = `${this.repoLink}/datasets/reference_datasets_data`; | |||
this.$axios.get(url).then((res) => { | |||
this.loadingLinkPage = false; | |||
if (!res.data) { | |||
this.showFlag = false; | |||
this.datasetList = []; | |||
return; | |||
} else { | |||
this.datasetList = res.data; | |||
this.datasetList.length | |||
? (this.showFlag = true) | |||
: (this.showFlag = false); | |||
} | |||
}); | |||
}, | |||
getDatasetList() { | |||
this.loadingPublicPage = true; | |||
let url = `${this.repoLink}/datasets/reference_datasets_available`; | |||
this.$axios | |||
.get(url, { | |||
params: this.paramsPublics, | |||
}) | |||
.then((res) => { | |||
this.publicDatasetList = JSON.parse(res.data.data); | |||
this.totalNum = parseInt(res.data.count); | |||
this.loadingPublicPage = false; | |||
}); | |||
}, | |||
submitReferDataset() { | |||
if (this.checkList.length > this.maxReferenceNum) { | |||
this.$message.error( | |||
this.i18n.dataset_over_nums.format(this.maxReferenceNum) | |||
); | |||
return; | |||
} | |||
let url = `${this.repoLink}/datasets/reference_datasets`; | |||
let data = this.qs.stringify( | |||
{ | |||
_csrf: csrf, | |||
dataset_id: this.checkList, | |||
}, | |||
{ arrayFormat: "repeat" } | |||
); | |||
this.$axios | |||
.post(url, data) | |||
.then((res) => { | |||
if (res.data.Code === 0) { | |||
this.$message.success(this.i18n.dataset_link_success); | |||
this.getSelectDatasetList(); | |||
} else { | |||
this.$message.error(res.data.Message); | |||
} | |||
}) | |||
.catch((err) => { | |||
this.$message.error(this.i18n.dataset_link_failed); | |||
console.log(err); | |||
}); | |||
}, | |||
}, | |||
filters: { | |||
transformTimestamp(timestamp) { | |||
const date = new Date(parseInt(timestamp) * 1000); | |||
const Y = date.getFullYear() + "-"; | |||
const M = | |||
(date.getMonth() + 1 < 10 | |||
? "0" + (date.getMonth() + 1) | |||
: date.getMonth() + 1) + "-"; | |||
const D = | |||
(date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " "; | |||
const dateString = Y + M + D; | |||
return dateString; | |||
}, | |||
}, | |||
watch: { | |||
search(val) { | |||
if (!val) { | |||
this.searchName(); | |||
} | |||
}, | |||
showFlag(val) { | |||
if (!val || this.isCurrentUrl) { | |||
document | |||
.getElementById("header-dataset") | |||
.setAttribute("href", this.repoLink + "/datasets"); | |||
} else { | |||
document | |||
.getElementById("header-dataset") | |||
.setAttribute("href", this.repoLink + "/datasets/reference_datasets"); | |||
} | |||
}, | |||
}, | |||
mounted() { | |||
this.getSelectDatasetList(); | |||
}, | |||
created() { | |||
this.repoLink = $(".reference-dataset").data("repolink") || ""; | |||
this.canWrite = $(".reference-dataset").data("canwrite"); | |||
this.isSigned = $(".reference-dataset").data("is-sign"); | |||
this.maxReferenceNum = $(".reference-dataset").data("max-reference-num"); | |||
this.isCurrentUrl = $(".reference-dataset").data("address"); | |||
if (document.documentElement.attributes["lang"].nodeValue == "en-US") { | |||
this.i18n = this.$locale.US; | |||
} else { | |||
this.i18n = this.$locale.CN; | |||
} | |||
}, | |||
beforeDestroy() {}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.dataset-search-vue { | |||
z-index: 9999; | |||
position: absolute; | |||
right: 31%; | |||
height: 30px; | |||
top: 60px; | |||
} | |||
.refer-dataset-card { | |||
cursor: pointer; | |||
box-shadow: 0px 4px 4px 0px rgba(232, 232, 232, 0.6); | |||
border: 1px solid rgba(232, 232, 232, 1); | |||
} | |||
.refer-dataset-card .refer-dataset-card-content { | |||
font-size: 16px; | |||
color: #0366d6; | |||
font-family: SourceHanSansSC-medium; | |||
height: 34px; | |||
font-weight: bold; | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
} | |||
.refer-dataset-card-title { | |||
display: flex; | |||
align-items: center; | |||
max-width: 80%; | |||
width: 100%; | |||
} | |||
.dataset-card-flavor { | |||
display: flex; | |||
align-items: center; | |||
padding: 0.3rem 0.5rem; | |||
border: #888888; | |||
border-top-right-radius: 0 !important; | |||
border-bottom-right-radius: 0 !important; | |||
margin-right: -1px; | |||
} | |||
.card-flavor-num { | |||
padding: 0.5rem; | |||
border: #888888; | |||
border-top-left-radius: 0 !important; | |||
border-bottom-left-radius: 0 !important; | |||
cursor: default !important; | |||
} | |||
.card-flavor-desc { | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 2; | |||
display: -webkit-box; | |||
overflow: hidden; | |||
color: #999999; | |||
font-size: 14px; | |||
margin-top: 10px; | |||
} | |||
.select-data-wrap { | |||
padding: 1rem 0; | |||
border-bottom: 1px solid rgba(0, 0, 0, 0.05); | |||
} | |||
.select-data-title { | |||
flex: 1; | |||
overflow: hidden; | |||
} | |||
.select-data-title .ref-data-title { | |||
font-size: 18px; | |||
color: #454545; | |||
font-weight: 700; | |||
display: flex; | |||
align-items: baseline; | |||
max-width: 100%; | |||
} | |||
.select-data-href { | |||
text-align: right; | |||
text-overflow: ellipsis; | |||
max-width: 35%; | |||
word-break: initial; | |||
margin-left: 1rem; | |||
white-space: nowrap; | |||
} | |||
/deep/ .el-checkbox-group .el-checkbox .el-checkbox__label { | |||
display: flex; | |||
max-width: 90%; | |||
} | |||
.select-data-right { | |||
overflow: hidden; | |||
vertical-align: middle; | |||
text-overflow: ellipsis; | |||
max-width: 100%; | |||
display: inline-block; | |||
} | |||
.data-multiple-wrap { | |||
-webkit-line-clamp: 3; | |||
-webkit-box-orient: vertical; | |||
display: -webkit-box; | |||
max-width: 100%; | |||
overflow: hidden; | |||
padding-top: 1rem; | |||
color: #888888; | |||
font: 12px; | |||
line-height: 20px; | |||
margin-left: 2rem; | |||
} | |||
.disabled1 { | |||
opacity: 0.45 !important; | |||
} | |||
</style> |
@@ -11,9 +11,9 @@ | |||
v-if="benchmarkNew" | |||
class="label-fix-width" | |||
style="font-weight: normal" | |||
>数据集</label | |||
>{{ i18n.dataset_label }}</label | |||
> | |||
<label v-else>数据集</label> | |||
<label v-else>{{ i18n.dataset_label }}</label> | |||
<span | |||
:class=" | |||
benchmarkNew === true ? 'dataset-train-span' : 'dataset-debug-span' | |||
@@ -38,7 +38,7 @@ | |||
type="text" | |||
class="disabled" | |||
style="width: 48.5%" | |||
placeholder="选择数据集文件" | |||
:placeholder="i18n.dataset_select_placeholder" | |||
required | |||
/> | |||
<input | |||
@@ -46,7 +46,7 @@ | |||
type="text" | |||
class="disabled" | |||
:required="required" | |||
placeholder="选择数据集文件" | |||
:placeholder="i18n.dataset_select_placeholder" | |||
/> | |||
</span> | |||
@@ -59,10 +59,10 @@ | |||
? 'select-dataset-button' | |||
: 'select-dataset-button-color' | |||
" | |||
>选择数据集 | |||
>{{ i18n.dataset_select }} | |||
</el-button> | |||
<el-dialog | |||
title="选择数据集" | |||
:title="i18n.dataset_select" | |||
:visible.sync="dialogVisible" | |||
:width="dialogWidth" | |||
> | |||
@@ -74,8 +74,8 @@ | |||
></i> | |||
<input | |||
type="text" | |||
placeholder="搜数据集名称/描述..." | |||
v-model="search" | |||
:placeholder="i18n.dataset_search_placeholder" | |||
v-model="search" | |||
@keydown.enter.stop.prevent="searchName" | |||
/> | |||
</div> | |||
@@ -90,7 +90,11 @@ | |||
> | |||
<el-tabs v-model="activeName" @tab-click="handleClick"> | |||
<!-- 当前项目的数据集 --> | |||
<el-tab-pane label="本项目" name="first" v-loading="loadingCurrent"> | |||
<el-tab-pane | |||
:label="i18n.dataset_current_repo" | |||
name="first" | |||
v-loading="loadingCurrent" | |||
> | |||
<el-row> | |||
<el-tree | |||
:data="currentDatasetList" | |||
@@ -141,6 +145,15 @@ | |||
class="dataset-repolink dataset-nowrap" | |||
@click.stop="return false;" | |||
> | |||
<i | |||
class="ri-links-line" | |||
style="color: #21ba45; margin-right: 0.3rem" | |||
:title="i18n.dataset_relate" | |||
v-if=" | |||
'/' + data.Repo.OwnerName + '/' + data.Repo.Name !== | |||
repoLink | |||
" | |||
></i> | |||
<a | |||
:href=" | |||
'/' + | |||
@@ -163,13 +176,13 @@ | |||
class="zip-loading" | |||
v-if="data.DecompressState === 2" | |||
> | |||
正在解压缩 | |||
{{ i18n.dataset_unziping }} | |||
</span> | |||
<span | |||
class="unzip-failed" | |||
v-if="data.DecompressState === 3" | |||
> | |||
解压失败 | |||
{{ i18n.dataset_unzip_failed }} | |||
</span> | |||
</span> | |||
</span> | |||
@@ -192,7 +205,11 @@ | |||
</div> | |||
</el-tab-pane> | |||
<!-- 我上传的数据集 --> | |||
<el-tab-pane label="我上传的" name="second" v-loading="loadingMy"> | |||
<el-tab-pane | |||
:label="i18n.dataset_my_upload" | |||
name="second" | |||
v-loading="loadingMy" | |||
> | |||
<el-row> | |||
<el-tree | |||
:data="myDatasetList" | |||
@@ -265,13 +282,13 @@ | |||
class="zip-loading" | |||
v-if="data.DecompressState === 2" | |||
> | |||
正在解压缩 | |||
{{ i18n.dataset_unziping }} | |||
</span> | |||
<span | |||
class="unzip-failed" | |||
v-if="data.DecompressState === 3" | |||
> | |||
解压失败 | |||
{{ i18n.dataset_unzip_failed }} | |||
</span> | |||
</span> | |||
</span> | |||
@@ -295,7 +312,7 @@ | |||
</el-tab-pane> | |||
<!-- 公开的数据集 --> | |||
<el-tab-pane | |||
label="公开数据集" | |||
:label="i18n.dataset_public" | |||
name="third" | |||
v-loading="loadingPublic" | |||
> | |||
@@ -371,13 +388,13 @@ | |||
class="zip-loading" | |||
v-if="data.DecompressState === 2" | |||
> | |||
正在解压缩 | |||
{{ i18n.dataset_unziping }} | |||
</span> | |||
<span | |||
class="unzip-failed" | |||
v-if="data.DecompressState === 3" | |||
> | |||
解压失败 | |||
{{ i18n.dataset_unzip_failed }} | |||
</span> | |||
</span> | |||
</span> | |||
@@ -401,7 +418,7 @@ | |||
</el-tab-pane> | |||
<!-- 我点赞的数据集 --> | |||
<el-tab-pane | |||
label="我收藏的" | |||
:label="i18n.dataset_collected" | |||
name="four" | |||
v-loading="loadingFavorite" | |||
> | |||
@@ -477,13 +494,13 @@ | |||
class="zip-loading" | |||
v-if="data.DecompressState === 2" | |||
> | |||
正在解压缩 | |||
{{ i18n.dataset_unziping }} | |||
</span> | |||
<span | |||
class="unzip-failed" | |||
v-if="data.DecompressState === 3" | |||
> | |||
解压失败 | |||
{{ i18n.dataset_unzip_failed }} | |||
</span> | |||
</span> | |||
</span> | |||
@@ -527,9 +544,9 @@ | |||
line-height: 40px; | |||
" | |||
> | |||
已选数据文件 | |||
{{ i18n.dataset_selected }} | |||
</div> | |||
<div style="flex: 1; margin-top: 1.5rem"> | |||
<div style="flex: 1; margin: 1.5rem 0; overflow-y: auto"> | |||
<el-checkbox-group v-model="checkList"> | |||
<el-checkbox | |||
v-for="(item, index) in selectDatasetArray" | |||
@@ -549,7 +566,7 @@ | |||
color: #fff; | |||
border: 1px solid #389e0d; | |||
" | |||
>确定</el-button | |||
>{{ i18n.dataset_ok }}</el-button | |||
> | |||
</div> | |||
</el-col> | |||
@@ -576,7 +593,7 @@ export default { | |||
activeName: "first", | |||
search: "", | |||
required: true, | |||
i18n: {}, | |||
type: 0, | |||
repoLink: "", | |||
selectDatasetArray: [], | |||
@@ -586,6 +603,8 @@ export default { | |||
confirmFlag: false, | |||
saveStatusList: [], | |||
// 初始化已选择的数据集列表 | |||
hasSelectDatasetList: [], | |||
//当前项目数据集页面配置的初始化 | |||
initCurrentPage: 1, | |||
totalNumCurrent: 0, | |||
@@ -644,6 +663,7 @@ export default { | |||
//tree 勾选触发事件 | |||
onCheck(data, checkedInfo) { | |||
this.hasSelectDatasetList = []; | |||
if ( | |||
this.selectDatasetArray.length === 0 || | |||
this.selectDatasetArray.every((item) => item.id !== data.id) | |||
@@ -654,10 +674,10 @@ export default { | |||
}) | |||
) { | |||
this.$refs[data.ref].setChecked(data.id, false, false); | |||
this.$message.warning("不能选择相同名称的数据文件"); | |||
this.$message.warning(this.i18n.dataset_not_equal_file); | |||
} else if (this.selectDatasetArray.length === 5) { | |||
this.$refs[data.ref].setChecked(data.id, false, false); | |||
this.$message.error("最多不超过五个文件"); | |||
this.$message.error(this.i18n.dataset_most); | |||
} else { | |||
this.selectDatasetArray.push(data); | |||
} | |||
@@ -671,9 +691,8 @@ export default { | |||
return item.label; | |||
}); | |||
this.saveStatusList = this.selectDatasetArray.map((item) => { | |||
return item.UUID; | |||
return item.id; | |||
}); | |||
// this.confirmDatasetList = this.saveStatusList.join(";"); | |||
}, | |||
//已选择数据集checkbox group 勾选事件 | |||
changeCheckbox(checked, data) { | |||
@@ -686,7 +705,6 @@ export default { | |||
}); | |||
this.selectDatasetArray.splice(index, 1); | |||
this.saveStatusList.splice(index, 1); | |||
// this.confirmDatasetList = this.saveStatusList.join(";"); | |||
}, | |||
tableHeaderStyle({ row, column, rowIndex, columnIndex }) { | |||
if (rowIndex === 0) { | |||
@@ -727,12 +745,17 @@ export default { | |||
"currentTree", | |||
this.paramsCurrent.page | |||
); | |||
this.initCurrentTreeNode = this.currentDatasetList[0]?.id ? [this.currentDatasetList[0].id] : []; | |||
this.initCurrentTreeNode = this.currentDatasetList[0]?.id | |||
? [this.currentDatasetList[0].id] | |||
: []; | |||
this.totalNumCurrent = parseInt(res.data.count); | |||
let setCheckedKeysList = this.currentDatasetList.reduce( | |||
(pre, cur) => { | |||
cur.Attachments.forEach((item) => { | |||
if (this.saveStatusList.includes(item.id)) { | |||
if ( | |||
this.saveStatusList.includes(item.id) || | |||
this.hasSelectDatasetList.includes(item.id) | |||
) { | |||
pre.push(item.id); | |||
} | |||
}); | |||
@@ -763,7 +786,9 @@ export default { | |||
"myTree", | |||
this.paramsMy.page | |||
); | |||
this.initMyTreeNode = this.myDatasetList[0]?.id ? [this.myDatasetList[0].id] : []; | |||
this.initMyTreeNode = this.myDatasetList[0]?.id | |||
? [this.myDatasetList[0].id] | |||
: []; | |||
this.totalNumMy = parseInt(res.data.count); | |||
let setCheckedKeysList = this.myDatasetList.reduce((pre, cur) => { | |||
cur.Attachments.forEach((item) => { | |||
@@ -796,7 +821,9 @@ export default { | |||
"publicTree", | |||
this.paramsPublics.page | |||
); | |||
this.initPublicTreeNode = this.publicDatasetList[0]?.id ? [this.publicDatasetList[0].id] : []; | |||
this.initPublicTreeNode = this.publicDatasetList[0]?.id | |||
? [this.publicDatasetList[0].id] | |||
: []; | |||
this.totalNumPublic = parseInt(res.data.count); | |||
let setCheckedKeysList = this.publicDatasetList.reduce((pre, cur) => { | |||
cur.Attachments.forEach((item) => { | |||
@@ -830,7 +857,9 @@ export default { | |||
"favoriteTree", | |||
this.paramsFavorite.page | |||
); | |||
this.initFavoriteTreeNode = this.MyFavoriteDatasetList[0]?.id ? [this.MyFavoriteDatasetList[0].id] : []; | |||
this.initFavoriteTreeNode = this.MyFavoriteDatasetList[0]?.id | |||
? [this.MyFavoriteDatasetList[0].id] | |||
: []; | |||
this.totalNumFavorite = parseInt(res.data.count); | |||
let setCheckedKeysList = this.MyFavoriteDatasetList.reduce( | |||
(pre, cur) => { | |||
@@ -949,13 +978,40 @@ export default { | |||
mounted() { | |||
this.type = $(".cloudbrain-type").data("cloudbrain-type"); | |||
this.repoLink = $(".cloudbrain-type").data("repo-link"); | |||
if ($(".cloudbrain-type").data("dataset-uuid")) { | |||
this.hasSelectDatasetList = $(".cloudbrain-type") | |||
.data("dataset-uuid") | |||
.split(";"); | |||
let hasSelectDatasetName = $(".cloudbrain-type") | |||
.data("dataset-name") | |||
.split(";"); | |||
if ( | |||
this.hasSelectDatasetList.length !== 0 && | |||
hasSelectDatasetName[0] !== "" | |||
) { | |||
this.saveStatusList = this.hasSelectDatasetList; | |||
this.checkList = hasSelectDatasetName; | |||
this.hasSelectDatasetList.forEach((item, index) => { | |||
this.selectDatasetArray.push({ | |||
id: item, | |||
label: hasSelectDatasetName[index], | |||
}); | |||
}); | |||
} | |||
this.confirmDataset(); | |||
} | |||
if ( | |||
location.href.indexOf("benchmark") !== -1 || | |||
location.href.indexOf("train-job") !== -1 | |||
location.href.indexOf("train-job") !== -1 || | |||
location.href.indexOf("inference") !== -1 | |||
) { | |||
this.benchmarkNew = true; | |||
} | |||
if (location.href.indexOf("modelarts/notebook/create") !== -1 || location.href.indexOf("/cloudbrain/create") !== -1) { | |||
if ( | |||
location.href.indexOf("modelarts/notebook/create") !== -1 || | |||
location.href.indexOf("/cloudbrain/create") !== -1 | |||
) { | |||
this.required = false; | |||
} | |||
window.onresize = () => { | |||
@@ -966,6 +1022,11 @@ export default { | |||
}, | |||
created() { | |||
this.setDialogWidth(); | |||
if (document.documentElement.attributes["lang"].nodeValue == "en-US") { | |||
this.i18n = this.$locale.US; | |||
} else { | |||
this.i18n = this.$locale.CN; | |||
} | |||
}, | |||
}; | |||
</script> | |||
@@ -1,9 +1,8 @@ | |||
<template> | |||
<div> | |||
<div class="ui container" style="width: 80%;"> | |||
<div class="ui grid"> | |||
<div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | |||
<div class="ui container" style="width: 100% !important;padding-right: 0;"> | |||
<div class="ui grid" style="margin: 0 !important"> | |||
<div class="row" style="border: 1px solid #d4d4d5;margin-top:0px;padding-top: 0;"> | |||
<div class="ui attached segment"> | |||
<div class="ui form ignore-dirty"> | |||
<div class="ui fluid action input"> | |||
@@ -31,8 +30,8 @@ | |||
<div class="ui six wide column right aligned" style="margin: 1rem 0;"> | |||
<a class="ui blue small button" href="/admin/images/commit_image">创建云脑镜像</a> | |||
</div> | |||
<div class="ui sixteen wide column" style="padding: 0;"> | |||
<el-table :data="tableDataCustom" style="width: 100%" :header-cell-style="tableHeaderStyle"> | |||
<div class="ui sixteen wide column" style="padding: 0;overflow-x: auto;"> | |||
<el-table :data="tableDataCustom" style="width: 100%;min-width:1700px;" :header-cell-style="tableHeaderStyle"> | |||
<el-table-column label="镜像Tag" min-width="19%" align="left" prop="tag"> | |||
<template slot-scope="scope"> | |||
<div style="display: flex;align-items: center;"> | |||
@@ -7,32 +7,32 @@ | |||
v-if="benchmarkNew" | |||
class="label-fix-width" | |||
style="font-weight: normal" | |||
>镜像</label | |||
>{{i18n.image_label}}</label | |||
> | |||
<label v-else>镜像</label> | |||
<label v-else>{{i18n.image_label}}</label> | |||
<input | |||
v-if="benchmarkNew" | |||
type="text" | |||
name="image" | |||
:value="imageAddress" | |||
style="width: 48.5%" | |||
placeholder="选择镜像或输入镜像地址" | |||
:placeholder="i18n.image_select_placeholder" | |||
/> | |||
<input | |||
v-else | |||
type="text" | |||
name="image" | |||
:value="imageAddress" | |||
placeholder="选择镜像或输入镜像地址" | |||
:placeholder="i18n.image_select_placeholder" | |||
/> | |||
<el-button | |||
type="text" | |||
@click="dialogVisible = true" | |||
icon="el-icon-plus" | |||
style="color: #0366d6" | |||
>选择镜像 | |||
>{{i18n.image_select}} | |||
</el-button> | |||
<el-dialog title="选择镜像" :visible.sync="dialogVisible" width="50%"> | |||
<el-dialog :title="i18n.image_select" :visible.sync="dialogVisible" width="50%"> | |||
<div | |||
class="ui icon input" | |||
style="z-index: 9999; position: absolute; right: 50px; height: 30px" | |||
@@ -43,12 +43,12 @@ | |||
></i> | |||
<input | |||
type="text" | |||
placeholder="搜镜像Tag/描述/标签..." | |||
:placeholder="i18n.image_search_placeholder" | |||
v-model="search" | |||
/> | |||
</div> | |||
<el-tabs v-model="activeName" @tab-click="handleClick"> | |||
<el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic"> | |||
<el-tab-pane :label="i18n.image_public" name="first" v-loading="loadingPublic"> | |||
<div | |||
style=" | |||
display: flex; | |||
@@ -120,7 +120,7 @@ | |||
selectImages(publicData.place, publicData.tag) | |||
" | |||
> | |||
使用 | |||
{{i18n.image_use}} | |||
</button> | |||
</div> | |||
</div> | |||
@@ -169,6 +169,7 @@ export default { | |||
}, | |||
tableDataPublic: [], | |||
loadingPublic: false, | |||
i18n: {}, | |||
}; | |||
}, | |||
methods: { | |||
@@ -236,7 +237,13 @@ export default { | |||
this.benchmarkNew = true; | |||
} | |||
}, | |||
created() {}, | |||
created() { | |||
if (document.documentElement.attributes["lang"].nodeValue == "en-US") { | |||
this.i18n = this.$locale.US; | |||
} else { | |||
this.i18n = this.$locale.CN; | |||
} | |||
}, | |||
}; | |||
</script> | |||
@@ -7,16 +7,16 @@ | |||
v-if="benchmarkNew" | |||
class="label-fix-width" | |||
style="font-weight: normal" | |||
>镜像</label | |||
>{{i18n.image_label}}</label | |||
> | |||
<label v-else>镜像</label> | |||
<label v-else>{{i18n.image_label}}</label> | |||
<input | |||
v-if="benchmarkNew" | |||
type="text" | |||
name="image" | |||
:value="imageAddress" | |||
style="width: 48.5%" | |||
placeholder="选择镜像或输入镜像地址" | |||
:placeholder="i18n.image_select_placeholder" | |||
required | |||
/> | |||
<input | |||
@@ -24,7 +24,7 @@ | |||
type="text" | |||
name="image" | |||
:value="imageAddress" | |||
placeholder="选择镜像或输入镜像地址" | |||
:placeholder="i18n.image_select_placeholder" | |||
required | |||
/> | |||
<el-button | |||
@@ -32,9 +32,9 @@ | |||
@click="dialogVisible = true" | |||
icon="el-icon-plus" | |||
style="color: #0366d6" | |||
>选择镜像 | |||
>{{i18n.image_select}} | |||
</el-button> | |||
<el-dialog title="选择镜像" :visible.sync="dialogVisible" width="50%"> | |||
<el-dialog :title="i18n.image_select" :visible.sync="dialogVisible" width="50%"> | |||
<div | |||
class="ui icon input" | |||
style="z-index: 9999; position: absolute; right: 50px; height: 30px" | |||
@@ -45,12 +45,12 @@ | |||
></i> | |||
<input | |||
type="text" | |||
placeholder="搜镜像Tag/描述/标签..." | |||
:placeholder="i18n.image_search_placeholder" | |||
v-model="search" | |||
/> | |||
</div> | |||
<el-tabs v-model="activeName" @tab-click="handleClick"> | |||
<el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic"> | |||
<el-tab-pane :label="i18n.image_public" name="first" v-loading="loadingPublic"> | |||
<div | |||
style=" | |||
display: flex; | |||
@@ -122,7 +122,7 @@ | |||
selectImages(publicData.place, publicData.tag) | |||
" | |||
> | |||
使用 | |||
{{i18n.image_use}} | |||
</button> | |||
</div> | |||
</div> | |||
@@ -142,7 +142,7 @@ | |||
</div> | |||
</el-tab-pane> | |||
<el-tab-pane label="我的镜像" name="second" v-loading="loadingCustom"> | |||
<el-tab-pane :label="i18n.image_my" name="second" v-loading="loadingCustom"> | |||
<div | |||
style=" | |||
display: flex; | |||
@@ -208,7 +208,7 @@ | |||
selectImages(customData.place, customData.tag) | |||
" | |||
> | |||
使用 | |||
{{i18n.image_use}} | |||
</button> | |||
<span | |||
v-if="customData.status === 0" | |||
@@ -217,7 +217,7 @@ | |||
<i class="CREATING"></i> | |||
<span | |||
style="margin-left: 0.4em; font-size: 12px; color: #5a5a5a" | |||
>提交中</span | |||
>{{i18n.image_commit}}</span | |||
> | |||
</span> | |||
<span | |||
@@ -228,11 +228,11 @@ | |||
<el-tooltip | |||
class="item" | |||
effect="dark" | |||
content="检测提交镜像是否大小超过20G!" | |||
:content="i18n.image_commit_content" | |||
placement="left" | |||
> | |||
<span style="margin-left: 0.4em; font-size: 12px; color: red" | |||
>提交失败</span | |||
>{{i18n.image_commit_failed}}</span | |||
> | |||
</el-tooltip> | |||
</span> | |||
@@ -254,7 +254,7 @@ | |||
</div> | |||
</el-tab-pane> | |||
<el-tab-pane label="我收藏的镜像" name="third"> | |||
<el-tab-pane :label="i18n.image_collected" name="third"> | |||
<div | |||
style=" | |||
display: flex; | |||
@@ -324,7 +324,7 @@ | |||
class="ui primary basic button mini" | |||
@click.stop.prevent="selectImages(starData.place, starData.tag)" | |||
> | |||
使用 | |||
{{i18n.image_use}} | |||
</button> | |||
</div> | |||
</div> | |||
@@ -368,7 +368,7 @@ export default { | |||
paramsPublic: { page: 1, pageSize: 5, q: "", recommend: false }, | |||
tableDataPublic: [], | |||
loadingPublic: false, | |||
i18n: {}, | |||
currentPageCustom: 1, | |||
pageSizeCustom: 5, | |||
totalNumCustom: 0, | |||
@@ -513,7 +513,13 @@ export default { | |||
this.benchmark = true; | |||
} | |||
}, | |||
created() {}, | |||
created() { | |||
if (document.documentElement.attributes["lang"].nodeValue == "en-US") { | |||
this.i18n = this.$locale.US; | |||
} else { | |||
this.i18n = this.$locale.CN; | |||
} | |||
}, | |||
}; | |||
</script> | |||
@@ -213,6 +213,35 @@ export default async function initCloudrainSow() { | |||
}); | |||
e.stopPropagation(); | |||
}); | |||
$(".delete-show-version").click(function (e) { | |||
const ID = this.dataset.jobid; | |||
const repoPath = this.dataset.repopath; | |||
const version_name = this.dataset.version; | |||
const url = `/api/v1/repos/${repoPath}/${ID}/del_version`; | |||
$(".ui.basic.modal") | |||
.modal({ | |||
onApprove: function () { | |||
$.post(url, { version_name: version_name }, (data) => { | |||
console.log(data); | |||
if (data.StatusOK === 0) { | |||
if (data.VersionListCount === 0) { | |||
location.href = `/${repoPath}`; | |||
} else { | |||
$("#accordion" + version_name).remove(); | |||
} | |||
refreshStatusShow(version_name, ID, repoPath); | |||
} else { | |||
return; | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
}, | |||
}) | |||
.modal("show"); | |||
e.stopPropagation(); | |||
}); | |||
function refreshStatusShow(version_name, ID, repoPath) { | |||
$.get( | |||
`/api/v1/repos/${repoPath}/${ID}?version_name=${version_name}`, | |||
@@ -390,7 +419,7 @@ export default async function initCloudrainSow() { | |||
html += "</a>"; | |||
html += "</span>"; | |||
html += "</td>"; | |||
html += "<td class='message seven wide'>"; | |||
html += "<td class='message1 seven wide'>"; | |||
if (data.Dirs[i].IsDir) { | |||
html += "<span class='truncate has-emoji'></span>"; | |||
} else { | |||
@@ -182,6 +182,15 @@ export default async function initCloudrain() { | |||
"CREATE_FAILED", | |||
"STOPPED", | |||
]; | |||
let deleteArray = [ | |||
"KILLED", | |||
"FAILED", | |||
"START_FAILED", | |||
"COMPLETED", | |||
"SUCCEEDED", | |||
"CREATE_FAILED", | |||
"STOPPED", | |||
]; | |||
$.get( | |||
`/api/v1/repos/${repoPath}/${jobID}?version_name=${versionname}`, | |||
(data) => { | |||
@@ -194,6 +203,10 @@ export default async function initCloudrain() { | |||
if (stopArray.includes(data.JobStatus)) { | |||
$("#" + versionname + "-stop").addClass("disabled"); | |||
} | |||
if (deleteArray.includes(data.JobStatus)) { | |||
$(`#${versionname}-delete`).removeClass("disabled"); | |||
$(`#${versionname}-delete`).addClass("blue"); | |||
} | |||
if (data.JobStatus === "COMPLETED") { | |||
$("#" + versionname + "-create-model") | |||
.removeClass("disabled") | |||
@@ -0,0 +1,204 @@ | |||
export const i18nVue = { | |||
CN: { | |||
computer_vision: "计算机视觉", | |||
natural_language_processing: "自然语言处理", | |||
speech_processing: "语音处理", | |||
computer_vision_natural_language_processing: "计算机视觉、自然语言处理", | |||
machine_translation: "机器翻译", | |||
question_answering_system: "问答系统", | |||
information_retrieval: "信息检索", | |||
knowledge_graph: "知识图谱", | |||
text_annotation: "文本标注", | |||
text_categorization: "文本分类", | |||
emotion_analysis: "情感分析", | |||
language_modeling: "语言建模", | |||
speech_recognition: "语音识别", | |||
automatic_digest: "自动文摘", | |||
information_extraction: "信息抽取", | |||
description_generation: "说明生成", | |||
image_classification: "图像分类", | |||
face_recognition: "人脸识别", | |||
image_search: "图像搜索", | |||
target_detection: "目标检测", | |||
image_description_generation: "图像描述生成", | |||
vehicle_license_plate_recognition: "车辆车牌识别", | |||
medical_image_analysis: "医学图像分析", | |||
unmanned: "无人驾驶", | |||
unmanned_security: "无人安防", | |||
drone: "无人机", | |||
vr_ar: "VR/AR", | |||
"2_d_vision": "2-D视觉", | |||
"2_5_d_vision": "2.5-D视觉", | |||
"3_d_reconstruction": "3D重构", | |||
image_processing: "图像处理", | |||
video_processing: "视频处理", | |||
visual_input_system: "视觉输入系统", | |||
speech_coding: "语音编码", | |||
speech_enhancement: "语音增强", | |||
speech_recognition: "语音识别", | |||
speech_synthesis: "语音合成", | |||
current_dataset: "当前数据集", | |||
linked_datasets: "关联数据集", | |||
unfavorite: "取消收藏", | |||
favorite: "收藏", | |||
disassociate: "取消关联", | |||
public_dataset: "公开数据集", | |||
selected_data_file: "已选数据集", | |||
sure: "确定", | |||
search_dataset: "搜数据集名称/描述...", | |||
citations: "引用次数", | |||
downloads: "下载次数", | |||
not_link_dataset: "还未关联过数据集", | |||
no_link_dataset_tips1: | |||
"您可以通过单击关联数据集按钮,将平台上公开数据集展示在这里。", | |||
dataset_instructions_for_use: "使用说明:可以参考启智AI协作平台", | |||
dataset_camp_course: "小白训练营课程", | |||
dataset_link_success: "关联数据集成功!", | |||
dataset_link_failed: "关联数据集失败!", | |||
dataset_over_nums: "关联超过?个数据集", | |||
cancel_link_dataset: "取消关联数据集?成功!", | |||
image_label: "镜像", | |||
image_select_placeholder: "选择镜像或输入镜像地址", | |||
image_select: "选择镜像", | |||
image_search_placeholder: "搜镜像Tag/描述/标签...", | |||
image_public: "公开镜像", | |||
image_use: "使用", | |||
image_my: "我的镜像", | |||
image_commit: "提交中", | |||
image_commit_content: "检测提交镜像是否大小超过20G!", | |||
image_commit_failed: "提交失败", | |||
image_collected: "我收藏的镜像", | |||
dataset_label: "数据集", | |||
dataset_select_placeholder: "选择数据集文件", | |||
dataset_select: "选择数据集", | |||
dataset_search_placeholder: "搜数据集名称/描述...", | |||
dataset_unziping: "正在解压缩", | |||
dataset_unzip_failed: "解压失败", | |||
dataset_my_upload: "我上传的", | |||
dataset_current_repo: "本项目", | |||
dataset_public: "公开数据集", | |||
dataset_relate: "关联数据集", | |||
dataset_collected: "我收藏的", | |||
dataset_selected: "已选数据文件", | |||
dataset_ok: "确定", | |||
dataset_not_equal_file: "不能选择相同名称的数据文件", | |||
dataset_most: "最多不超过五个文件", | |||
model_name: "模型名称", | |||
model_version: "版本", | |||
model_version_num: "版本数", | |||
model_size: "模型大小", | |||
model_egine: "模型框架", | |||
model_compute_resource: "计算资源", | |||
model_create_time: "创建时间", | |||
model_creator: "创建者", | |||
model_operation: "操作", | |||
model_create_new_ver: "创建新版本", | |||
model_download: "下载", | |||
model_delete: "删除", | |||
model_create_title: "导入新模型", | |||
model_create_version_title: "创建模型新版本", | |||
}, | |||
US: { | |||
computer_vision: "computer vision", | |||
natural_language_processing: "natural language processing", | |||
speech_processing: "speech processing", | |||
computer_vision_natural_language_processing: | |||
"computer vision and natural language processing", | |||
machine_translation: "machine translation", | |||
question_answering_system: "question answering system", | |||
information_retrieval: "information retrieval", | |||
knowledge_graph: "knowledge graph", | |||
text_annotation: "text annotation", | |||
text_categorization: "text categorization", | |||
emotion_analysis: "emotion analysis", | |||
language_modeling: "language modeling", | |||
speech_recognition: "speech recognition", | |||
automatic_digest: "automatic digest", | |||
information_extraction: "information extraction", | |||
description_generation: "description generation", | |||
image_classification: "image classification", | |||
face_recognition: "face recognition", | |||
image_search: "image search", | |||
target_detection: "target detection", | |||
image_description_generation: "image description generation", | |||
vehicle_license_plate_recognition: "vehicle license plate recognition", | |||
medical_image_analysis: "medical image analysis", | |||
unmanned: "unmanned", | |||
unmanned_security: "unmanned security", | |||
drone: "drone", | |||
vr_ar: "VR/AR", | |||
"2_d_vision": "2.D vision", | |||
"2.5_d_vision": "2.5D vision", | |||
"3_d_reconstruction": "3Dreconstruction", | |||
image_processing: "image processing", | |||
video_processing: "video processing", | |||
visual_input_system: "visual input system", | |||
speech_coding: "speech coding", | |||
speech_enhancement: "speech enhancement", | |||
speech_recognition: "speech recognition", | |||
speech_synthesis: "speech synthesis", | |||
current_dataset: "Current Dataset", | |||
linked_datasets: "Linked Datasets", | |||
unfavorite: "UnLike", | |||
favorite: "Like", | |||
disassociate: "Unlink", | |||
public_dataset: "Public Dataset", | |||
selected_data_file: "Selected DataSets", | |||
sure: "OK", | |||
search_dataset: "Search dataset name/description ...", | |||
citations: "Citations", | |||
downloads: "Downloads", | |||
not_link_dataset: "No datasets have been linked yet", | |||
no_link_dataset_tips1: | |||
"You can display public datasets on the platform here by clicking the Linked Datasets button.", | |||
dataset_instructions_for_use: | |||
"Instructions for use: You can refer to OpenI AI Collaboration Platform ", | |||
dataset_camp_course: " OpenI_Learning", | |||
dataset_link_success: "Linked dataset succeeded!", | |||
dataset_link_failed: "Linked dataset Failed!", | |||
dataset_over_nums: "Linked over ? datasets!", | |||
cancel_link_dataset: "Cancel Linked dataset ? succeeded!", | |||
image_label: "Image", | |||
image_select_placeholder: "Select image or input image url", | |||
image_select: "Select Image", | |||
image_search_placeholder: "Search image tag/description/label...", | |||
image_public: "Public Image", | |||
image_use: "Use", | |||
image_my: "My Images", | |||
image_commit: "Commiting", | |||
image_commit_content: | |||
"Check whether the size of the submitted image exceeds 20g.", | |||
image_commit_failed: "Commit failed", | |||
image_collected: "My collected images", | |||
dataset_label: "Dataset", | |||
dataset_select_placeholder: "Select dataset file", | |||
dataset_select: "Select dataset", | |||
dataset_search_placeholder: "Search dataset name/description ...", | |||
dataset_unziping: "Decompressing", | |||
dataset_unzip_failed: "Decompression failed", | |||
dataset_my_upload: "Upload by me", | |||
dataset_current_repo: "Current Repository", | |||
dataset_public: "Public dataset", | |||
dataset_collected: "My collection", | |||
dataset_relate: "Related dataset", | |||
dataset_selected: "Selected dataset file", | |||
dataset_ok: "OK", | |||
dataset_not_equal_file: "Cannot select a data file with the same name.", | |||
dataset_most: "Up to five files.", | |||
model_name: "Model Name", | |||
model_version: "Version", | |||
model_version_num: "Total", | |||
model_size: "Size", | |||
model_egine: "Engine", | |||
model_compute_resource: "Compute Resource", | |||
model_create_time: "Created Time", | |||
model_creator: "Creator", | |||
model_operation: "Operation", | |||
model_create_new_ver: "New Version", | |||
model_download: "Download", | |||
model_delete: "Delete", | |||
model_create_title: "Import new model", | |||
model_create_version_title: "Create a new version of the model", | |||
}, | |||
}; |
@@ -46,15 +46,19 @@ import initCloudrain from "./features/cloudrbanin.js"; | |||
import initCloudrainSow from "./features/cloudbrainShow.js"; | |||
import initImage from "./features/images.js"; | |||
import selectDataset from "./components/dataset/selectDataset.vue"; | |||
import referenceDataset from "./components/dataset/referenceDataset.vue"; | |||
// import $ from 'jquery.js' | |||
import router from "./router/index.js"; | |||
import { Message } from "element-ui"; | |||
import { i18nVue } from "./features/i18nVue.js"; | |||
Vue.use(ElementUI); | |||
Vue.prototype.$axios = axios; | |||
Vue.prototype.$Cookies = Cookies; | |||
Vue.prototype.qs = qs; | |||
Vue.prototype.$message = Message; | |||
Vue.prototype.$locale = i18nVue; | |||
const { AppSubUrl, StaticUrlPrefix, csrf } = window.config; | |||
Object.defineProperty(Vue.prototype, "$echarts", { | |||
@@ -2900,6 +2904,7 @@ $(document).ready(async () => { | |||
initVueDataAnalysis(); | |||
initVueWxAutorize(); | |||
initVueselectDataset(); | |||
initVuereferenceDataset(); | |||
initTeamSettings(); | |||
initCtrlEnterSubmit(); | |||
initNavbarContentToggle(); | |||
@@ -3520,7 +3525,7 @@ function initVueComponents() { | |||
`${self.reposFilter}:${self.archivedFilter}:${self.privateFilter}`, | |||
count | |||
); | |||
self.finalPage = Math.floor(count / self.searchLimit) + 1; | |||
self.finalPage = Math.ceil(count / self.searchLimit); | |||
self.updateHistory(); | |||
} | |||
}).always(() => { | |||
@@ -4532,6 +4537,16 @@ function initVueselectDataset() { | |||
render: (h) => h(selectDataset), | |||
}); | |||
} | |||
function initVuereferenceDataset() { | |||
const el = document.getElementById("reference-dataset"); | |||
if (!el) { | |||
return; | |||
} | |||
new Vue({ | |||
el: el, | |||
render: (h) => h(referenceDataset), | |||
}); | |||
} | |||
window.timeAddManual = function () { | |||
$(".mini.modal") | |||
.modal({ | |||
@@ -5086,7 +5101,7 @@ function initChartsNpu() { | |||
axisLabel: { | |||
interval: "auto", | |||
}, | |||
name: "时间(min)", | |||
name: "", | |||
}, | |||
yAxis: { | |||
show: true, | |||
@@ -5142,7 +5157,9 @@ function initChartsNpu() { | |||
}; | |||
return seriesOption; | |||
}); | |||
let xAxisValue = res.Interval === 1 ? "时间(min)" : "时间(hour)"; | |||
let xLength = res.MetricsInfo[0].value.length; | |||
options.xAxis.name = xAxisValue; | |||
options.xAxis.data = Array.from( | |||
{ length: xLength }, | |||
(_, index) => index | |||
@@ -1,5 +1,5 @@ | |||
.admin { | |||
padding-top: 15px; | |||
padding-top: 15px !important; | |||
.table.segment { | |||
padding: 0; | |||
@@ -75,4 +75,58 @@ | |||
white-space: pre-wrap; | |||
word-wrap: break-word; | |||
} | |||
display: flex; | |||
.new-menu.navbar { | |||
width: 230px !important; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start !important; | |||
border-bottom: none !important; | |||
background-color: transparent !important; | |||
.item-container { | |||
display: flex; | |||
flex-direction: column; | |||
padding-top: 8px; | |||
padding-bottom: 8px; | |||
margin-left: 10px !important; | |||
margin-right: 10px !important; | |||
border: 1px solid #d4d4d5; | |||
border-radius: 4px; | |||
box-shadow: 0 1px 2px 0 rgb(34 36 38 / 15%); | |||
background-color: #fafafa !important; | |||
.item { | |||
align-self: flex-start !important; | |||
width: 100%; | |||
padding-left: 20px; | |||
&.active { | |||
color: #40a9ff !important; | |||
border-right: 4px solid #40a9ff; | |||
border-radius: 0 !important; | |||
border-bottom: none !important; | |||
background-color: rgb(255, 255, 255); | |||
} | |||
&:hover { | |||
background-color: #ffffff !important; | |||
} | |||
&:active { | |||
border-color: transparent !important; | |||
} | |||
&.item-next { | |||
padding-left: 45px; | |||
} | |||
&.item-first { | |||
color: rgba(0,0,0,.87); | |||
&:hover { | |||
background-color: transparent !important; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
>.ui.container { | |||
flex: 1 !important; | |||
padding-right: 10px; | |||
} | |||
} |
@@ -100,7 +100,7 @@ | |||
} | |||
.issue.title { | |||
width: 80%; | |||
width: 100%; | |||
} | |||
.push.news .content ul { | |||
@@ -0,0 +1,41 @@ | |||
import service from '../service'; | |||
// 算力积分概要 | |||
export const getPointAccount = () => { | |||
return service({ | |||
url: '/reward/point/account', | |||
method: 'get', | |||
params: {}, | |||
}); | |||
} | |||
// 算力积分获取、消耗明细 | |||
// operate-INCREASE 表示获取明细 DECREASE表示消耗明细, page-当前页, pageSize-每页条数 | |||
export const getPointList = (params) => { | |||
return service({ | |||
url: '/reward/point/record/list', | |||
method: 'get', | |||
params, | |||
}); | |||
} | |||
// 管理员充值、扣减用户积分 | |||
// TargetUserId, OperateType-INCREASE,DECREASE, Amount, Remark, RewardType-POINT | |||
export const setPointOperate = (data) => { | |||
return service({ | |||
url: '/operation/reward/point/account/operate', | |||
method: 'post', | |||
data, | |||
params: {} | |||
}); | |||
} | |||
// 算力积分页面 | |||
export const getPoint = () => { | |||
return service({ | |||
url: '/reward/point', | |||
method: 'get', | |||
params: {}, | |||
data: {}, | |||
}); | |||
} |