@@ -1141,3 +1141,9 @@ growth_issue=0.2 | |||||
growth_contributors=0.2 | growth_contributors=0.2 | ||||
growth_commit=0.2 | growth_commit=0.2 | ||||
growth_comments=0.2 | growth_comments=0.2 | ||||
[grampus] | |||||
USERNAME = | |||||
PASSWORD = | |||||
SERVER_HOST = |
@@ -0,0 +1,294 @@ | |||||
package grampus | |||||
import ( | |||||
"code.gitea.io/gitea/modules/timeutil" | |||||
"strconv" | |||||
"code.gitea.io/gitea/models" | |||||
"code.gitea.io/gitea/modules/context" | |||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/notification" | |||||
) | |||||
const ( | |||||
//notebook | |||||
storageTypeOBS = "obs" | |||||
autoStopDuration = 4 * 60 * 60 | |||||
autoStopDurationMs = 4 * 60 * 60 * 1000 | |||||
DataSetMountPath = "/home/ma-user/work" | |||||
NotebookEnv = "Python3" | |||||
NotebookType = "Ascend" | |||||
FlavorInfo = "Ascend: 1*Ascend 910 CPU: 24 核 96GiB (modelarts.kat1.xlarge)" | |||||
//train-job | |||||
// ResourcePools = "{\"resource_pool\":[{\"id\":\"pool1328035d\", \"value\":\"专属资源池\"}]}" | |||||
// Engines = "{\"engine\":[{\"id\":1, \"value\":\"Ascend-Powered-Engine\"}]}" | |||||
// EngineVersions = "{\"version\":[{\"id\":118,\"value\":\"MindSpore-1.0.0-c75-python3.7-euleros2.8-aarch64\"}," + | |||||
// "{\"id\":119,\"value\":\"MindSpore-1.1.1-c76-python3.7-euleros2.8-aarch64\"}," + | |||||
// "{\"id\":120,\"value\":\"MindSpore-1.1.1-c76-tr5-python3.7-euleros2.8-aarch64\"}," + | |||||
// "{\"id\":117,\"value\":\"TF-1.15-c75-python3.7-euleros2.8-aarch64\"}" + | |||||
// "]}" | |||||
// TrainJobFlavorInfo = "{\"flavor\":[{\"code\":\"modelarts.bm.910.arm.public.2\",\"value\":\"Ascend : 2 * Ascend 910 CPU:48 核 512GiB\"}," + | |||||
// "{\"code\":\"modelarts.bm.910.arm.public.8\",\"value\":\"Ascend : 8 * Ascend 910 CPU:192 核 2048GiB\"}," + | |||||
// "{\"code\":\"modelarts.bm.910.arm.public.4\",\"value\":\"Ascend : 4 * Ascend 910 CPU:96 核 1024GiB\"}," + | |||||
// "{\"code\":\"modelarts.bm.910.arm.public.1\",\"value\":\"Ascend : 1 * Ascend 910 CPU:24 核 256GiB\"}" + | |||||
// "]}" | |||||
CodePath = "/code/" | |||||
OutputPath = "/output/" | |||||
ResultPath = "/result/" | |||||
LogPath = "/log/" | |||||
JobPath = "/job/" | |||||
OrderDesc = "desc" //向下查询 | |||||
OrderAsc = "asc" //向上查询 | |||||
Lines = 500 | |||||
TrainUrl = "train_url" | |||||
DataUrl = "data_url" | |||||
ResultUrl = "result_url" | |||||
CkptUrl = "ckpt_url" | |||||
DeviceTarget = "device_target" | |||||
Ascend = "Ascend" | |||||
PerPage = 10 | |||||
IsLatestVersion = "1" | |||||
NotLatestVersion = "0" | |||||
VersionCount = 1 | |||||
SortByCreateTime = "create_time" | |||||
ConfigTypeCustom = "custom" | |||||
TotalVersionCount = 1 | |||||
) | |||||
var ( | |||||
poolInfos *models.PoolInfos | |||||
FlavorInfos *models.FlavorInfos | |||||
ImageInfos *models.ImageInfosModelArts | |||||
) | |||||
type GenerateTrainJobReq struct { | |||||
JobName string | |||||
DisplayJobName string | |||||
Uuid string | |||||
Description string | |||||
CodeObsPath string | |||||
BootFile string | |||||
BootFileUrl string | |||||
DataUrl string | |||||
TrainUrl string | |||||
FlavorCode string | |||||
LogUrl string | |||||
PoolID string | |||||
WorkServerNumber int | |||||
EngineID int64 | |||||
Parameters []models.Parameter | |||||
CommitID string | |||||
IsLatestVersion string | |||||
Params string | |||||
BranchName string | |||||
PreVersionId int64 | |||||
PreVersionName string | |||||
FlavorName string | |||||
VersionCount int | |||||
EngineName string | |||||
TotalVersionCount int | |||||
} | |||||
type GenerateInferenceJobReq struct { | |||||
JobName string | |||||
DisplayJobName string | |||||
Uuid string | |||||
Description string | |||||
CodeObsPath string | |||||
BootFile string | |||||
BootFileUrl string | |||||
DataUrl string | |||||
TrainUrl string | |||||
FlavorCode string | |||||
LogUrl string | |||||
PoolID string | |||||
WorkServerNumber int | |||||
EngineID int64 | |||||
Parameters []models.Parameter | |||||
CommitID string | |||||
Params string | |||||
BranchName string | |||||
FlavorName string | |||||
EngineName string | |||||
LabelName string | |||||
IsLatestVersion string | |||||
VersionCount int | |||||
TotalVersionCount int | |||||
ModelName string | |||||
ModelVersion string | |||||
CkptName string | |||||
ResultUrl string | |||||
} | |||||
type VersionInfo struct { | |||||
Version []struct { | |||||
ID int `json:"id"` | |||||
Value string `json:"value"` | |||||
} `json:"version"` | |||||
} | |||||
type Flavor struct { | |||||
Info []struct { | |||||
Code string `json:"code"` | |||||
Value string `json:"value"` | |||||
} `json:"flavor"` | |||||
} | |||||
type Engine struct { | |||||
Info []struct { | |||||
ID int `json:"id"` | |||||
Value string `json:"value"` | |||||
} `json:"engine"` | |||||
} | |||||
type ResourcePool struct { | |||||
Info []struct { | |||||
ID string `json:"id"` | |||||
Value string `json:"value"` | |||||
} `json:"resource_pool"` | |||||
} | |||||
// type Parameter struct { | |||||
// Label string `json:"label"` | |||||
// Value string `json:"value"` | |||||
// } | |||||
// type Parameters struct { | |||||
// Parameter []Parameter `json:"parameter"` | |||||
// } | |||||
type Parameters struct { | |||||
Parameter []struct { | |||||
Label string `json:"label"` | |||||
Value string `json:"value"` | |||||
} `json:"parameter"` | |||||
} | |||||
func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error) { | |||||
createTime := timeutil.TimeStampNow() | |||||
jobResult, err := createTrainJob(models.CreateTrainJobParams{ | |||||
JobName: req.JobName, | |||||
Description: req.Description, | |||||
Config: models.Config{ | |||||
WorkServerNum: req.WorkServerNumber, | |||||
AppUrl: req.CodeObsPath, | |||||
BootFileUrl: req.BootFileUrl, | |||||
DataUrl: req.DataUrl, | |||||
EngineID: req.EngineID, | |||||
TrainUrl: req.TrainUrl, | |||||
LogUrl: req.LogUrl, | |||||
PoolID: req.PoolID, | |||||
CreateVersion: true, | |||||
Flavor: models.Flavor{ | |||||
Code: req.FlavorCode, | |||||
}, | |||||
Parameter: req.Parameters, | |||||
}, | |||||
}) | |||||
if err != nil { | |||||
log.Error("CreateJob failed: %v", 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), | |||||
UserID: ctx.User.ID, | |||||
RepoID: ctx.Repo.Repository.ID, | |||||
JobID: jobId, | |||||
JobName: req.JobName, | |||||
DisplayJobName: req.DisplayJobName, | |||||
JobType: string(models.JobTypeTrain), | |||||
Type: models.TypeCloudBrainTwo, | |||||
VersionID: jobResult.VersionID, | |||||
VersionName: jobResult.VersionName, | |||||
Uuid: req.Uuid, | |||||
DatasetName: attach.Name, | |||||
CommitID: req.CommitID, | |||||
IsLatestVersion: req.IsLatestVersion, | |||||
ComputeResource: models.NPUResource, | |||||
EngineID: req.EngineID, | |||||
TrainUrl: req.TrainUrl, | |||||
BranchName: req.BranchName, | |||||
Parameters: req.Params, | |||||
BootFile: req.BootFile, | |||||
DataUrl: req.DataUrl, | |||||
LogUrl: req.LogUrl, | |||||
FlavorCode: req.FlavorCode, | |||||
Description: req.Description, | |||||
WorkServerNumber: req.WorkServerNumber, | |||||
FlavorName: req.FlavorName, | |||||
EngineName: req.EngineName, | |||||
VersionCount: req.VersionCount, | |||||
TotalVersionCount: req.TotalVersionCount, | |||||
CreatedUnix: createTime, | |||||
UpdatedUnix: createTime, | |||||
}) | |||||
if err != nil { | |||||
log.Error("CreateCloudbrain(%s) failed:%v", req.DisplayJobName, err.Error()) | |||||
return err | |||||
} | |||||
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.DisplayJobName, models.ActionCreateTrainTask) | |||||
return nil | |||||
} | |||||
func TransTrainJobStatus(status int) string { | |||||
switch status { | |||||
case 0: | |||||
return "UNKNOWN" | |||||
case 1: | |||||
return "INIT" | |||||
case 2: | |||||
return "IMAGE_CREATING" | |||||
case 3: | |||||
return "IMAGE_FAILED" | |||||
case 4: | |||||
return "SUBMIT_TRYING" | |||||
case 5: | |||||
return "SUBMIT_FAILED" | |||||
case 6: | |||||
return "DELETE_FAILED" | |||||
case 7: | |||||
return "WAITING" | |||||
case 8: | |||||
return "RUNNING" | |||||
case 9: | |||||
return "KILLING" | |||||
case 10: | |||||
return "COMPLETED" | |||||
case 11: | |||||
return "FAILED" | |||||
case 12: | |||||
return "KILLED" | |||||
case 13: | |||||
return "CANCELED" | |||||
case 14: | |||||
return "LOST" | |||||
case 15: | |||||
return "SCALING" | |||||
case 16: | |||||
return "SUBMIT_MODEL_FAILED" | |||||
case 17: | |||||
return "DEPLOY_SERVICE_FAILED" | |||||
case 18: | |||||
return "CHECK_INIT" | |||||
case 19: | |||||
return "CHECK_RUNNING" | |||||
case 20: | |||||
return "CHECK_RUNNING_COMPLETED" | |||||
case 21: | |||||
return "CHECK_FAILED" | |||||
default: | |||||
return strconv.Itoa(status) | |||||
} | |||||
} |
@@ -528,6 +528,13 @@ var ( | |||||
FlavorInfos string | FlavorInfos string | ||||
TrainJobFLAVORINFOS string | TrainJobFLAVORINFOS string | ||||
//grampus config | |||||
Grampus = struct { | |||||
Host string | |||||
UserName string | |||||
Password string | |||||
}{} | |||||
//elk config | //elk config | ||||
ElkUrl string | ElkUrl string | ||||
ElkUser string | ElkUser string | ||||
@@ -1382,6 +1389,15 @@ func NewContext() { | |||||
Course.OrgName = sec.Key("org_name").MustString("") | Course.OrgName = sec.Key("org_name").MustString("") | ||||
Course.TeamName = sec.Key("team_name").MustString("") | Course.TeamName = sec.Key("team_name").MustString("") | ||||
GetGrampusConfig() | |||||
} | |||||
func GetGrampusConfig() { | |||||
sec := Cfg.Section("grampus") | |||||
Grampus.Host = sec.Key("SERVER_HOST").MustString("") | |||||
Grampus.UserName = sec.Key("USERNAME").MustString("") | |||||
Grampus.Password = sec.Key("PASSWORD").MustString("") | |||||
} | } | ||||
func SetRadarMapConfig() { | func SetRadarMapConfig() { | ||||
@@ -1,22 +1,435 @@ | |||||
package repo | package repo | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/base" | |||||
"code.gitea.io/gitea/modules/auth" | |||||
"code.gitea.io/gitea/modules/git" | |||||
"code.gitea.io/gitea/modules/modelarts" | |||||
"code.gitea.io/gitea/modules/util" | |||||
"encoding/json" | |||||
"io/ioutil" | |||||
"net/http" | "net/http" | ||||
"os" | |||||
"path" | |||||
"strconv" | |||||
"strings" | |||||
"time" | |||||
"code.gitea.io/gitea/models" | |||||
"code.gitea.io/gitea/modules/base" | |||||
"code.gitea.io/gitea/modules/cloudbrain" | |||||
"code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/setting" | |||||
) | ) | ||||
const ( | const ( | ||||
tplGrampusTrainJobNew base.TplName = "repo/grampus/trainjob/new" | |||||
tplGrampusTrainJobShow base.TplName = "repo/grampus/trainjob/show" | |||||
//GPU | |||||
tplGrampusTrainJobGPUNew base.TplName = "repo/grampus/trainjob/gpu/new" | |||||
tplGrampusTrainJobGPUShow base.TplName = "repo/grampus/trainjob/gpu/show" | |||||
//NPU | |||||
tplGrampusTrainJobNPUNew base.TplName = "repo/grampus/trainjob/npu/new" | |||||
tplGrampusTrainJobNPUShow base.TplName = "repo/grampus/trainjob/npu/show" | |||||
) | ) | ||||
func GrampusNew(ctx *context.Context) { | |||||
err := cloudBrainNewDataPrepare(ctx) | |||||
func GrampusTrainJobGPUNew(ctx *context.Context) { | |||||
err := grampusGpuNewDataPrepare(ctx) | |||||
if err != nil { | |||||
ctx.ServerError("get new train-job info failed", err) | |||||
return | |||||
} | |||||
ctx.HTML(http.StatusOK, tplGrampusTrainJobGPUNew) | |||||
} | |||||
func grampusGpuNewDataPrepare(ctx *context.Context) error { | |||||
ctx.Data["PageIsCloudBrain"] = true | |||||
t := time.Now() | |||||
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
ctx.Data["display_job_name"] = displayJobName | |||||
//get valid images | |||||
result, err := cloudbrain.GetImages() | |||||
if err != nil { | |||||
ctx.Data["error"] = err.Error() | |||||
log.Error("cloudbrain.GetImages failed:", err.Error(), ctx.Data["MsgID"]) | |||||
} | |||||
for i, payload := range result.Payload.ImageInfo { | |||||
if strings.HasPrefix(result.Payload.ImageInfo[i].Place, "192.168") { | |||||
result.Payload.ImageInfo[i].PlaceView = payload.Place[strings.Index(payload.Place, "/"):len(payload.Place)] | |||||
} else { | |||||
result.Payload.ImageInfo[i].PlaceView = payload.Place | |||||
} | |||||
} | |||||
ctx.Data["images"] = result.Payload.ImageInfo | |||||
resultPublic, err := cloudbrain.GetPublicImages() | |||||
if err != nil { | |||||
ctx.Data["error"] = err.Error() | |||||
log.Error("cloudbrain.GetPublicImages failed:", err.Error(), ctx.Data["MsgID"]) | |||||
} | |||||
for i, payload := range resultPublic.Payload.ImageInfo { | |||||
if strings.HasPrefix(resultPublic.Payload.ImageInfo[i].Place, "192.168") { | |||||
resultPublic.Payload.ImageInfo[i].PlaceView = payload.Place[strings.Index(payload.Place, "/"):len(payload.Place)] | |||||
} else { | |||||
resultPublic.Payload.ImageInfo[i].PlaceView = payload.Place | |||||
} | |||||
} | |||||
ctx.Data["public_images"] = resultPublic.Payload.ImageInfo | |||||
//get valid dataset | |||||
attachs, err := models.GetAllUserAttachments(ctx.User.ID) | |||||
if err != nil { | |||||
log.Error("GetAllUserAttachments failed: %v", err, ctx.Data["MsgID"]) | |||||
return err | |||||
} | |||||
ctx.Data["attachments"] = attachs | |||||
ctx.Data["command"] = cloudbrain.Command | |||||
ctx.Data["code_path"] = cloudbrain.CodeMountPath | |||||
ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath | |||||
ctx.Data["model_path"] = cloudbrain.ModelMountPath | |||||
ctx.Data["benchmark_path"] = cloudbrain.BenchMarkMountPath | |||||
ctx.Data["is_benchmark_enabled"] = setting.IsBenchmarkEnabled | |||||
//get valid resource specs | |||||
if categories == nil { | |||||
json.Unmarshal([]byte(setting.BenchmarkCategory), &categories) | |||||
} | |||||
ctx.Data["benchmark_categories"] = categories.Category | |||||
ctx.Data["benchmark_types"] = GetBenchmarkTypes(ctx).BenchmarkType | |||||
if gpuInfos == nil { | |||||
json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | |||||
} | |||||
ctx.Data["gpu_types"] = gpuInfos.GpuInfo | |||||
if trainGpuInfos == nil { | |||||
json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||||
} | |||||
ctx.Data["train_gpu_types"] = trainGpuInfos.GpuInfo | |||||
if benchmarkGpuInfos == nil { | |||||
json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | |||||
} | |||||
ctx.Data["benchmark_gpu_types"] = benchmarkGpuInfos.GpuInfo | |||||
if benchmarkResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.BenchmarkResourceSpecs), &benchmarkResourceSpecs) | |||||
} | |||||
ctx.Data["benchmark_resource_specs"] = benchmarkResourceSpecs.ResourceSpec | |||||
if cloudbrain.ResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||||
} | |||||
ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | |||||
if cloudbrain.TrainResourceSpecs == nil { | |||||
json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||||
} | |||||
ctx.Data["train_resource_specs"] = cloudbrain.TrainResourceSpecs.ResourceSpec | |||||
ctx.Data["params"] = "" | |||||
ctx.Data["branchName"] = ctx.Repo.BranchName | |||||
ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | |||||
ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | |||||
ctx.Data["brainscore_path"] = cloudbrain.BrainScoreMountPath | |||||
ctx.Data["is_brainscore_enabled"] = setting.IsBrainScoreEnabled | |||||
ctx.Data["cloudbraintype"] = models.TypeCloudBrainOne | |||||
ctx.Data["benchmarkMode"] = ctx.Query("benchmarkMode") | |||||
return nil | |||||
} | |||||
func GrampusTrainJobNPUNew(ctx *context.Context) { | |||||
err := trainJobNpuNewDataPrepare(ctx) | |||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("get new train-job info failed", err) | ctx.ServerError("get new train-job info failed", err) | ||||
return | return | ||||
} | } | ||||
ctx.HTML(http.StatusOK, tplGrampusTrainJobNew) | |||||
ctx.HTML(200, tplGrampusTrainJobNPUNew) | |||||
} | |||||
func trainJobNpuNewDataPrepare(ctx *context.Context) error { | |||||
ctx.Data["PageIsCloudBrain"] = true | |||||
t := time.Now() | |||||
var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
ctx.Data["display_job_name"] = displayJobName | |||||
//get valid dataset | |||||
attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||||
if err != nil { | |||||
ctx.ServerError("GetAllUserAttachments failed:", err) | |||||
return err | |||||
} | |||||
ctx.Data["attachments"] = attachs | |||||
//get valid resource specs | |||||
var resourcePools modelarts.ResourcePool | |||||
if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil { | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return err | |||||
} | |||||
ctx.Data["resource_pools"] = resourcePools.Info | |||||
var engines modelarts.Engine | |||||
if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil { | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return err | |||||
} | |||||
ctx.Data["engines"] = engines.Info | |||||
var versionInfos modelarts.VersionInfo | |||||
if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil { | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return err | |||||
} | |||||
ctx.Data["engine_versions"] = versionInfos.Version | |||||
var flavorInfos modelarts.Flavor | |||||
if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return err | |||||
} | |||||
ctx.Data["flavor_infos"] = flavorInfos.Info | |||||
ctx.Data["params"] = "" | |||||
ctx.Data["branchName"] = ctx.Repo.BranchName | |||||
configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | |||||
if err != nil { | |||||
ctx.ServerError("getConfigList failed:", err) | |||||
return err | |||||
} | |||||
ctx.Data["config_list"] = configList.ParaConfigs | |||||
ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo | |||||
return nil | |||||
} | |||||
func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) { | |||||
VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | |||||
displayJobName := form.DisplayJobName | |||||
jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||||
uuid := form.Attachment | |||||
description := form.Description | |||||
workServerNumber := form.WorkServerNumber | |||||
engineID := form.EngineID | |||||
bootFile := form.BootFile | |||||
flavorCode := form.Flavor | |||||
params := form.Params | |||||
poolID := form.PoolID | |||||
isSaveParam := form.IsSaveParam | |||||
repo := ctx.Repo.Repository | |||||
codeLocalPath := setting.JobPath + jobName + modelarts.CodePath | |||||
codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath | |||||
outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/" | |||||
logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/" | |||||
dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/" | |||||
branch_name := form.BranchName | |||||
isLatestVersion := modelarts.IsLatestVersion | |||||
FlavorName := form.FlavorName | |||||
VersionCount := modelarts.VersionCount | |||||
EngineName := form.EngineName | |||||
count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) | |||||
if err != nil { | |||||
log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("system error", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} else { | |||||
if count >= 1 { | |||||
log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
} | |||||
if err := paramCheckCreateTrainJob(form); err != nil { | |||||
log.Error("paramCheckCreateTrainJob failed:(%v)", err) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
//Determine whether the task name of the task in the project is duplicated | |||||
tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeTrain), displayJobName) | |||||
if err == nil { | |||||
if len(tasks) != 0 { | |||||
log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("the job name did already exist", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
} else { | |||||
if !models.IsErrJobNotExist(err) { | |||||
log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("system error", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
} | |||||
//todo: del the codeLocalPath | |||||
_, err = ioutil.ReadDir(codeLocalPath) | |||||
if err == nil { | |||||
os.RemoveAll(codeLocalPath) | |||||
} | |||||
gitRepo, _ := git.OpenRepository(repo.RepoPath()) | |||||
commitID, _ := gitRepo.GetBranchCommitID(branch_name) | |||||
if err := downloadCode(repo, codeLocalPath, branch_name); err != nil { | |||||
log.Error("downloadCode failed, server timed out: %s (%v)", repo.FullName(), err) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("Create task failed, server timed out", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
//todo: upload code (send to file_server todo this work?) | |||||
if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath + VersionOutputPath + "/"); err != nil { | |||||
log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("Failed to obsMkdir_output", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.LogPath + VersionOutputPath + "/"); err != nil { | |||||
log.Error("Failed to obsMkdir_log: %s (%v)", repo.FullName(), err) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("Failed to obsMkdir_log", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
// parentDir := VersionOutputPath + "/" | |||||
if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil { | |||||
// if err := uploadCodeToObs(codeLocalPath, jobName, parentDir); err != nil { | |||||
log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("Failed to uploadCodeToObs", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
var parameters models.Parameters | |||||
param := make([]models.Parameter, 0) | |||||
existDeviceTarget := false | |||||
if len(params) != 0 { | |||||
err := json.Unmarshal([]byte(params), ¶meters) | |||||
if err != nil { | |||||
log.Error("Failed to Unmarshal params: %s (%v)", params, err) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
for _, parameter := range parameters.Parameter { | |||||
if parameter.Label == modelarts.DeviceTarget { | |||||
existDeviceTarget = true | |||||
} | |||||
if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | |||||
param = append(param, models.Parameter{ | |||||
Label: parameter.Label, | |||||
Value: parameter.Value, | |||||
}) | |||||
} | |||||
} | |||||
} | |||||
if !existDeviceTarget { | |||||
param = append(param, models.Parameter{ | |||||
Label: modelarts.DeviceTarget, | |||||
Value: modelarts.Ascend, | |||||
}) | |||||
} | |||||
//save param config | |||||
if isSaveParam == "on" { | |||||
saveparams := append(param, models.Parameter{ | |||||
Label: modelarts.TrainUrl, | |||||
Value: outputObsPath, | |||||
}, models.Parameter{ | |||||
Label: modelarts.DataUrl, | |||||
Value: dataPath, | |||||
}) | |||||
if form.ParameterTemplateName == "" { | |||||
log.Error("ParameterTemplateName is empty") | |||||
trainJobNewDataPrepare(ctx) | |||||
ctx.RenderWithErr("保存作业参数时,作业参数名称不能为空", tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
_, err := modelarts.CreateTrainJobConfig(models.CreateConfigParams{ | |||||
ConfigName: form.ParameterTemplateName, | |||||
Description: form.PrameterDescription, | |||||
DataUrl: dataPath, | |||||
AppUrl: codeObsPath, | |||||
BootFileUrl: codeObsPath + bootFile, | |||||
TrainUrl: outputObsPath, | |||||
Flavor: models.Flavor{ | |||||
Code: flavorCode, | |||||
}, | |||||
WorkServerNum: workServerNumber, | |||||
EngineID: int64(engineID), | |||||
LogUrl: logObsPath, | |||||
PoolID: poolID, | |||||
Parameter: saveparams, | |||||
}) | |||||
if err != nil { | |||||
log.Error("Failed to CreateTrainJobConfig: %v", err) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr("保存作业参数失败:"+err.Error(), tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
} | |||||
req := &modelarts.GenerateTrainJobReq{ | |||||
JobName: jobName, | |||||
DisplayJobName: displayJobName, | |||||
DataUrl: dataPath, | |||||
Description: description, | |||||
CodeObsPath: codeObsPath, | |||||
BootFileUrl: codeObsPath + bootFile, | |||||
BootFile: bootFile, | |||||
TrainUrl: outputObsPath, | |||||
FlavorCode: flavorCode, | |||||
WorkServerNumber: workServerNumber, | |||||
EngineID: int64(engineID), | |||||
LogUrl: logObsPath, | |||||
PoolID: poolID, | |||||
Uuid: uuid, | |||||
Parameters: param, | |||||
CommitID: commitID, | |||||
IsLatestVersion: isLatestVersion, | |||||
BranchName: branch_name, | |||||
Params: form.Params, | |||||
FlavorName: FlavorName, | |||||
EngineName: EngineName, | |||||
VersionCount: VersionCount, | |||||
TotalVersionCount: modelarts.TotalVersionCount, | |||||
} | |||||
//将params转换Parameters.Parameter,出错时返回给前端 | |||||
var Parameters modelarts.Parameters | |||||
if err := json.Unmarshal([]byte(params), &Parameters); err != nil { | |||||
ctx.ServerError("json.Unmarshal failed:", err) | |||||
return | |||||
} | |||||
err = modelarts.GenerateTrainJob(ctx, req) | |||||
if err != nil { | |||||
log.Error("GenerateTrainJob failed:%v", err.Error()) | |||||
trainJobErrorNewDataPrepare(ctx, form) | |||||
ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) | |||||
return | |||||
} | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
} | } |
@@ -1085,14 +1085,26 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
}, context.RepoRef()) | }, context.RepoRef()) | ||||
m.Group("/grampus", func() { | m.Group("/grampus", func() { | ||||
m.Group("/train-job", func() { | m.Group("/train-job", func() { | ||||
m.Group("/:jobid", func() { | |||||
m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||||
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
m.Group("/gpu", func() { | |||||
m.Group("/:jobid", func() { | |||||
m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||||
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
}) | |||||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusTrainJobGPUNew) | |||||
//m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.GrampusTrainJobCreate) | |||||
}) | |||||
m.Group("/npu", func() { | |||||
m.Group("/:jobid", func() { | |||||
m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||||
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
}) | |||||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusTrainJobNPUNew) | |||||
//m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.GrampusTrainJobCreate) | |||||
}) | }) | ||||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusNew) | |||||
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.GrampusCreate) | |||||
}) | }) | ||||
}, context.RepoRef()) | }, context.RepoRef()) | ||||
m.Group("/modelmanage", func() { | m.Group("/modelmanage", func() { | ||||
@@ -0,0 +1,447 @@ | |||||
{{template "base/head" .}} | |||||
<style> | |||||
.unite{ | |||||
font-family: SourceHanSansSC-medium !important; | |||||
color: rgba(16, 16, 16, 100) !important; | |||||
} | |||||
.title{ | |||||
font-size: 16px !important; | |||||
padding-left: 3rem !important; | |||||
} | |||||
.min_title{ | |||||
font-size: 14px !important; | |||||
padding-left: 6rem !important; | |||||
margin-bottom: 2rem !important; | |||||
} | |||||
.width{ | |||||
width:100% !important; | |||||
} | |||||
.width80{ | |||||
width: 80.7% !important; | |||||
margin-left: 10px; | |||||
} | |||||
.width806{ | |||||
width: 80.6% !important; | |||||
margin-left: -2px; | |||||
} | |||||
.width85{ | |||||
width: 85% !important; | |||||
margin-left: 4.5rem !important; | |||||
} | |||||
.width81{ | |||||
margin-left: 1.5rem !important; | |||||
width: 81% !important; | |||||
} | |||||
.add{font-size: 18px; | |||||
padding: 0.5rem; | |||||
border: 1px solid rgba(187, 187, 187, 100); | |||||
border-radius: 0px 5px 5px 0px; | |||||
line-height: 21px; | |||||
text-align: center; | |||||
color: #C2C7CC; | |||||
} | |||||
.min{ | |||||
font-size: 18px; | |||||
padding: 0.5rem; | |||||
border: 1px solid rgba(187, 187, 187, 100); | |||||
border-radius: 5px 0px 0px 5px; | |||||
line-height: 21px; | |||||
text-align: center; | |||||
color: #C2C7CC; | |||||
} | |||||
</style> | |||||
<!-- <div class="ui page dimmer"> | |||||
<div class="ui text loader">{{.i18n.Tr "loading"}}</div> | |||||
</div> --> | |||||
<div id="mask"> | |||||
<div id="loadingPage"> | |||||
<div class="rect1"></div> | |||||
<div class="rect2"></div> | |||||
<div class="rect3"></div> | |||||
<div class="rect4"></div> | |||||
<div class="rect5"></div> | |||||
</div> | |||||
</div> | |||||
<div class="repository"> | |||||
{{template "repo/header" .}} | |||||
<div class="ui container"> | |||||
{{template "base/alert" .}} | |||||
<h4 class="ui top attached header"> | |||||
{{.i18n.Tr "repo.modelarts.train_job.new"}} | |||||
</h4> | |||||
<div class="ui attached segment"> | |||||
<!-- equal width --> | |||||
<form class="ui form" action="{{.Link}}" method="post"> | |||||
{{.CsrfTokenHtml}} | |||||
<input type="hidden" name="action" value="update"> | |||||
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
<input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
<div class="ui blue mini menu compact selectcloudbrain"> | |||||
<a class="active item" href="{{.RepoLink}}/grampus/train-job/gpu/create"> | |||||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||||
<path fill="none" d="M0 0h24v24H0z"/> | |||||
<path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||||
</svg> | |||||
CPU/GPU | |||||
</a> | |||||
<a class="item" href="{{.RepoLink}}/grampus/train-job/npu/create"> | |||||
<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 class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
</div> | |||||
<div class="unite min_title inline field"> | |||||
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||||
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
</div> | |||||
<div class="ui divider"></div> | |||||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||||
<select class="ui dropdown width80 left2" id="code_version" name="branch_name"> | |||||
{{if .branch_name}} | |||||
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||||
{{range $k, $v :=.Branches}} | |||||
{{ if ne $v $.branch_name }} | |||||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
{{end}} | |||||
{{end}} | |||||
{{else}} | |||||
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||||
{{range $k, $v :=.Branches}} | |||||
{{ if ne $v $.branchName }} | |||||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
{{end}} | |||||
{{end}} | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="inline required field" style="display: none;"> | |||||
<label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||||
<select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | |||||
<option name="job_type" value="TRAIN">TRAIN</option> | |||||
</select> | |||||
</div> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||||
<select id="cloudbrain_gpu_type" class="ui search width806 dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||||
{{range .train_gpu_types}} | |||||
<option value="{{.Queue}}">{{.Value}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<!-- <div class="required unite min_title inline field" style="position: relative;"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}} </label> | |||||
<input class="width81" type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" required autofocus maxlength="255"> | |||||
<i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | |||||
<datalist class="ui search" id="cloudbrain_image" name="image"> | |||||
{{range .images}} | |||||
<option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
{{end}} | |||||
{{range .public_images}} | |||||
<option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
{{end}} | |||||
</datalist> | |||||
</div> --> | |||||
<div id="images-new-cb"> | |||||
</div> | |||||
<div class="inline unite min_title field required"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
{{if .bootFile}} | |||||
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
{{else}} | |||||
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||||
{{end}} | |||||
<span> | |||||
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||||
</span> | |||||
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a> | |||||
</div> | |||||
{{template "custom/select_dataset_train" .}} | |||||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||||
<div class="inline unite min_title field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||||
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||||
<input id="store_run_para" type="hidden" name="run_para_list"> | |||||
<div class="dynamic field" style="margin-top: 1rem;"> | |||||
{{if .params}} | |||||
{{if ne 0 (len .params)}} | |||||
{{range $k ,$v := .params}} | |||||
<div class="two fields width85" id="para{{$k}}"> | |||||
<div class="field"> | |||||
<input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
</div> | |||||
<div class="field"> | |||||
<input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
</div> | |||||
<span> | |||||
<i class="trash icon"></i> | |||||
</span> | |||||
</div> | |||||
{{end}} | |||||
{{end}} | |||||
{{end}} | |||||
</div> | |||||
</div> | |||||
<div class="required inline unite min_title field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
<select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | |||||
{{range .train_resource_specs}} | |||||
<option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="inline unite min_title field"> | |||||
<button class="ui create_train_job green button"> | |||||
{{.i18n.Tr "repo.cloudbrain.new"}} | |||||
</button> | |||||
<a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||||
</div> | |||||
<!-- 模态框 --> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} | |||||
<script> | |||||
//let url_href = window.location.pathname.split('create')[0] | |||||
//$(".ui.button").attr('href',url_href) | |||||
$('select.dropdown') | |||||
.dropdown(); | |||||
$('.menu .item') | |||||
.tab(); | |||||
let sever_num = $('#trainjob_work_server_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){ | |||||
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"}}> ' + | |||||
'</div> ' + | |||||
'<div class="field"> ' + | |||||
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
'</div>'+ | |||||
'<span>' + | |||||
'<i class="trash icon">' + | |||||
'</i>' + | |||||
'</span>' + | |||||
'</div>' | |||||
$(".dynamic.field").append(value) | |||||
} | |||||
$('#add_run_para').click(function(){ | |||||
var len = $(".dynamic.field .two.fields").length | |||||
Add_parameter(len) | |||||
}); | |||||
$(".dynamic.field").on("click",".trash.icon", function() { | |||||
var index = $(this).parent().parent().index() | |||||
$(this).parent().parent().remove() | |||||
var len = $(".dynamic.field .two.fields").length | |||||
$(".dynamic.field .two.fields").each(function(){ | |||||
var cur_index = $(this).index() | |||||
$(this).attr('id', 'para' + cur_index) | |||||
}) | |||||
}); | |||||
$('.ui.parameter.green.button').click(function(){ | |||||
var parameters = []; | |||||
$('table tr').each(function() { | |||||
$(this).find('td:eq(1)').each(function(){ | |||||
parameters.push($(this).text()); | |||||
}) | |||||
$(this).find('input').each(function(){ | |||||
parameters.push($(this).text()) | |||||
}) | |||||
}); | |||||
$('.ui.parameter.modal') | |||||
.modal('hide'); | |||||
for(var i = 2; i < parameters.length; i++){ | |||||
switch(i) { | |||||
// 数据集uuid待完成 | |||||
// case (2): | |||||
// console.log(1) | |||||
// break; | |||||
// $("#trainjob_datasets").val(parameters[i]); | |||||
// console.log($("#trainjob_datasets").val()) | |||||
case (3): | |||||
$("input[name='boot_file']").val(parameters[i]); | |||||
break; | |||||
case (4): | |||||
var para = parameters[i].split(" ") | |||||
for(var j = 0; j < para.length; j++){ | |||||
var para_name = para[j].split('=')[0] | |||||
var para_value = para[j].split('=')[1] | |||||
var len = $(".dynamic.field .two.fields").length | |||||
Add_parameter(len) | |||||
var pid = 'para' + len | |||||
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
} | |||||
break; | |||||
// 数据集pool_id待完成 | |||||
// case (5): | |||||
// $("select[name='pool_id']").val(parameters[i]); | |||||
// break; | |||||
case (6): | |||||
$("input[name='work_server_number']").val(parameters[i]); | |||||
break; | |||||
} | |||||
} | |||||
}) | |||||
$('.ui.save.checkbox').click(function(){ | |||||
$(this).checkbox({ | |||||
onChange: function(){ | |||||
if ($('.ui.save.checkbox').checkbox('is checked')){ | |||||
$('#save_para').removeClass("disabled") | |||||
}else{ | |||||
$('#save_para').addClass("disabled") | |||||
} | |||||
} | |||||
}); | |||||
}) | |||||
$('.question.circle.icon').hover(function(){ | |||||
$(this).popup('show') | |||||
}); | |||||
$(".item.active.parameter_config").click(function(){ | |||||
$('.ui.parameter.modal') | |||||
.modal('setting', 'closable', false) | |||||
.modal('show'); | |||||
}) | |||||
$('.ui.deny.button').click(function(){ | |||||
$('.ui.parameter.modal') | |||||
.modal('hide'); | |||||
}) | |||||
$('select.dropdown') | |||||
.dropdown(); | |||||
function validate(){ | |||||
$('.ui.form') | |||||
.form({ | |||||
on: 'blur', | |||||
fields: { | |||||
boot_file: { | |||||
identifier : 'boot_file', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/.+\.py$/g]', | |||||
} | |||||
] | |||||
}, | |||||
display_job_name:{ | |||||
identifier : 'display_job_name', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
} | |||||
] | |||||
}, | |||||
attachment:{ | |||||
identifier : 'attachment', | |||||
rules: [ | |||||
{ | |||||
type: 'empty', | |||||
} | |||||
] | |||||
}, | |||||
work_server_number: { | |||||
identifier : 'work_server_number', | |||||
rules: [ | |||||
{ | |||||
type : 'integer[1..25]', | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
onSuccess: function(){ | |||||
// $('.ui.page.dimmer').dimmer('show') | |||||
document.getElementById("mask").style.display = "block" | |||||
}, | |||||
onFailure: function(e){ | |||||
return false; | |||||
} | |||||
}) | |||||
} | |||||
document.onreadystatechange = function() { | |||||
if (document.readyState === "complete") { | |||||
document.getElementById("mask").style.display = "none" | |||||
} | |||||
} | |||||
function send_run_para(){ | |||||
var run_parameters = [] | |||||
var msg = {} | |||||
$(".dynamic.field .two.fields").each(function(){ | |||||
var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
run_parameters.push({"label": para_name, "value": para_value}) | |||||
}) | |||||
msg["parameter"] = run_parameters | |||||
msg = JSON.stringify(msg) | |||||
$('#store_run_para').val(msg) | |||||
} | |||||
function get_name(){ | |||||
let name1=$("#engine_name .text").text() | |||||
let name2=$("#flaver_name .text").text() | |||||
$("input#ai_engine_name").val(name1) | |||||
$("input#ai_flaver_name").val(name2) | |||||
} | |||||
$('.ui.create_train_job.green.button').click(function(e) { | |||||
get_name() | |||||
send_run_para() | |||||
validate() | |||||
}) | |||||
</script> |
@@ -0,0 +1,731 @@ | |||||
{{template "base/head" .}} | |||||
<style> | |||||
.according-panel-heading { | |||||
box-sizing: border-box; | |||||
padding: 8px 16px; | |||||
color: #252b3a; | |||||
background-color: #f2f5fc; | |||||
line-height: 1.5; | |||||
cursor: pointer; | |||||
-moz-user-select: none; | |||||
-webkit-user-select: none; | |||||
-ms-user-select: none; | |||||
-khtml-user-select: none; | |||||
user-select: none; | |||||
} | |||||
.accordion-panel-title { | |||||
margin-top: 0; | |||||
margin-bottom: 0; | |||||
color: #252b3a; | |||||
} | |||||
.accordion-panel-title-content { | |||||
vertical-align: middle; | |||||
display: inline-block; | |||||
width: calc(100% - 32px); | |||||
cursor: default; | |||||
} | |||||
.acc-margin-bottom { | |||||
margin-bottom: 5px; | |||||
} | |||||
.title_text { | |||||
font-size: 12px; | |||||
} | |||||
.ac-display-inblock { | |||||
display: inline-block; | |||||
} | |||||
.cti-mgRight-sm { | |||||
margin-right: 8px; | |||||
} | |||||
.ac-text-normal { | |||||
font-size: 14px; | |||||
color: #575d6c; | |||||
} | |||||
.uc-accordionTitle-black { | |||||
color: #333; | |||||
} | |||||
.accordion-border { | |||||
border: 1px solid #cce2ff; | |||||
} | |||||
.padding0 { | |||||
padding: 0 !important; | |||||
} | |||||
.content-pad { | |||||
padding: 15px 35px; | |||||
} | |||||
.content-margin { | |||||
margin: 10px 5px; | |||||
} | |||||
.tab_2_content { | |||||
min-height: 360px; | |||||
margin-left: 10px; | |||||
} | |||||
.ac-grid { | |||||
display: block; | |||||
*zoom: 1; | |||||
} | |||||
.ac-grid-col { | |||||
float: left; | |||||
width: 100%; | |||||
} | |||||
.ac-grid-col2 .ac-grid-col { | |||||
width: 50%; | |||||
} | |||||
.ti-form { | |||||
text-align: left; | |||||
max-width: 100%; | |||||
vertical-align: middle; | |||||
} | |||||
.ti-form>tbody { | |||||
font-size: 12px; | |||||
} | |||||
.ti-form>tbody, | |||||
.ti-form>tbody>tr { | |||||
vertical-align: inherit; | |||||
} | |||||
.ti-text-form-label { | |||||
padding-bottom: 20px; | |||||
padding-right: 20px; | |||||
color: #8a8e99; | |||||
font-size: 12px; | |||||
white-space: nowrap !important; | |||||
width: 80px; | |||||
line-height: 30px; | |||||
} | |||||
.ti-text-form-content { | |||||
line-height: 30px; | |||||
padding-bottom: 20px; | |||||
} | |||||
.ti-form>tbody>tr>td { | |||||
vertical-align: top; | |||||
white-space: normal; | |||||
} | |||||
td, | |||||
th { | |||||
padding: 0; | |||||
} | |||||
.info_text { | |||||
padding-bottom: 20px; | |||||
padding-right: 20px; | |||||
font-size: 12px; | |||||
} | |||||
.ac-grid-col .text-span { | |||||
width: 450px; | |||||
overflow: hidden; | |||||
text-overflow: ellipsis; | |||||
white-space: nowrap; | |||||
} | |||||
.redo-color { | |||||
color: #3291F8; | |||||
} | |||||
.ti-action-menu-item:not(:last-child) { | |||||
margin-right: 10px; | |||||
padding-right: 11px; | |||||
text-decoration: none !important; | |||||
color: #526ecc; | |||||
cursor: pointer; | |||||
display: inline-block; | |||||
-moz-user-select: none; | |||||
-webkit-user-select: none; | |||||
-ms-user-select: none; | |||||
-khtml-user-select: none; | |||||
user-select: none; | |||||
position: relative; | |||||
} | |||||
.ti-action-menu-item:not(:last-child):after { | |||||
content: ""; | |||||
display: inline-block; | |||||
position: absolute; | |||||
height: 12px; | |||||
right: 0; | |||||
top: 50%; | |||||
-webkit-transform: translateY(-6px); | |||||
-ms-transform: translateY(-6px); | |||||
-o-transform: translateY(-6px); | |||||
transform: translateY(-6px); | |||||
border-right: 1px solid #dfe1e6; | |||||
} | |||||
.text-width80 { | |||||
width: 100px; | |||||
line-height: 30px; | |||||
} | |||||
.border-according { | |||||
border: 1px solid #dfe1e6; | |||||
} | |||||
.disabled { | |||||
cursor: default; | |||||
pointer-events: none; | |||||
color: rgba(0, 0, 0, .6) !important; | |||||
opacity: .45 !important; | |||||
} | |||||
.pad20 { | |||||
border: 0px !important; | |||||
} | |||||
.model_file_bread { | |||||
margin-bottom: -0.5rem !important; | |||||
padding-left: 1rem; | |||||
padding-top: 0.5rem; | |||||
} | |||||
</style> | |||||
<div id="mask"> | |||||
<div id="loadingPage"> | |||||
<div class="rect1"></div> | |||||
<div class="rect2"></div> | |||||
<div class="rect3"></div> | |||||
<div class="rect4"></div> | |||||
<div class="rect5"></div> | |||||
</div> | |||||
</div> | |||||
<div class="repository"> | |||||
{{template "repo/header" .}} | |||||
<div class="ui container"> | |||||
<h4 class="ui header" id="vertical-segment"> | |||||
<div class="ui breadcrumb"> | |||||
<a class="section" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||||
{{.i18n.Tr "repo.cloudbrain"}} | |||||
</a> | |||||
<div class="divider"> / </div> | |||||
<a class="section" href="{{$.RepoLink}}/modelarts/train-job"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job"}} | |||||
</a> | |||||
<div class="divider"> / </div> | |||||
<div class="active section">{{.displayJobName}}</div> | |||||
</div> | |||||
</h4> | |||||
{{range $k ,$v := .version_list_task}} | |||||
<div class="ui accordion border-according" id="accordion{{.VersionName}}" | |||||
data-repopath="{{$.RepoRelPath}}/cloudbrain" data-jobid="{{.ID}}" data-version="{{.VersionName}}"> | |||||
<input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||||
<div class="{{if eq $k 0}}active{{end}} title padding0"> | |||||
<div class="according-panel-heading"> | |||||
<div class="accordion-panel-title"> | |||||
<i class="dropdown icon"></i> | |||||
<span class="accordion-panel-title-content"> | |||||
<span> | |||||
<div class="ac-display-inblock title_text acc-margin-bottom"> | |||||
<span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||||
<span id="{{.VersionName}}-status-span"><i id="icon" | |||||
style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" | |||||
style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
</span> | |||||
<span | |||||
class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||||
<span class="cti-mgRight-sm uc-accordionTitle-black" | |||||
id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||||
</div> | |||||
</span> | |||||
</span> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="{{if eq $k 0}}active{{end}} content"> | |||||
<div class="content-pad"> | |||||
<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" data-tab="four{{$k}}" | |||||
onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | |||||
</div> | |||||
<div class="ui tab active" data-tab="first{{$k}}"> | |||||
<div style="padding-top: 10px;"> | |||||
<div class="tab_2_content"> | |||||
<div class="ac-grid ac-grid-col2"> | |||||
<div class="ac-grid-col"> | |||||
<table class="ti-form"> | |||||
<tbody class="ti-text-form"> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.cloudbrain_task"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{.DisplayJobName}} | |||||
</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.status"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||||
{{.Status}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
<span style="font-size: 12px;" | |||||
class="">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" | |||||
id="{{.VersionName}}-duration"> | |||||
{{$.duration}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{$.resource_type}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{$.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}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
<div class="ac-grid-col"> | |||||
<table class="ti-form"> | |||||
<tbody class="ti-text-form"> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "cloudbrain.mirror"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||||
{{.Image}} | |||||
</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.code_version"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{.BranchName}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w"> | |||||
{{.BootFile}} | |||||
</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"> | |||||
{{.DatasetName}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr class="ti-no-ng-animate"> | |||||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
{{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" title="{{.Parameters}}"> | |||||
{{.Parameters}} | |||||
</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.description"}} | |||||
</td> | |||||
<td class="ti-text-form-content"> | |||||
<div class="text-span text-span-w" title="{{.Description}}"> | |||||
{{.Description}} | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui tab" data-tab="second{{$k}}"> | |||||
<div> | |||||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
<div id="header"></div> | |||||
</div> | |||||
<div class="ui attached log" id="log{{.VersionName}}" | |||||
style="height: 390px !important; overflow: auto;"> | |||||
<input type="hidden" id="json_value" value="{{$.result.JobStatus.AppExitDiagnostics}}"> | |||||
<input type="hidden" id="ExitDiagnostics" value="{{$.ExitDiagnostics}}"> | |||||
<span id="info_display" class="info_text"> | |||||
</span> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui tab" data-tab="third{{$k}}"> | |||||
<div> | |||||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
<div id="header"></div> | |||||
</div> | |||||
<div class="ui attached log" id="log{{.VersionName}}" | |||||
style="height: 300px !important; overflow: auto;"> | |||||
<input type="hidden" name="end_line" value> | |||||
<input type="hidden" name="start_line" value> | |||||
<pre id="log_file{{.VersionName}}"></pre> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="ui tab" data-tab="four{{$k}}"> | |||||
<input type="hidden" name="model{{.VersionName}}" value="-1"> | |||||
<input type="hidden" name="modelback{{.VersionName}}" value="-1"> | |||||
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'> | |||||
<div class="active section">{{.VersionName}}</div> | |||||
<div class="divider"> / </div> | |||||
</div> | |||||
<div id="dir_list{{.VersionName}}"> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{end}} {{template "base/paginate" .}} | |||||
</div> | |||||
<!-- 确认模态框 --> | |||||
<div id="deletemodel"> | |||||
<div class="ui basic modal"> | |||||
<div class="ui icon header"> | |||||
<i class="trash icon"></i> 删除任务 | |||||
</div> | |||||
<div class="content"> | |||||
<p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
</div> | |||||
<div class="actions"> | |||||
<div class="ui red basic inverted cancel button"> | |||||
<i class="remove icon"></i> 取消操作 | |||||
</div> | |||||
<div class="ui green basic inverted ok button"> | |||||
<i class="checkmark icon"></i> 确定操作 | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} | |||||
<script> | |||||
$('.menu .item').tab() | |||||
$(document).ready(function () { | |||||
$('.ui.accordion').accordion({ selector: { trigger: '.icon' } }); | |||||
}); | |||||
$(document).ready(function () { | |||||
$('.secondary.menu .item').tab(); | |||||
}); | |||||
let userName | |||||
let repoPath | |||||
let jobID | |||||
let downlaodFlag = {{ $.canDownload }} | |||||
let taskID = {{ $.task.ID }} | |||||
let realJobName = {{ $.task.JobName }} | |||||
$(document).ready(function () { | |||||
let url = window.location.href; | |||||
let urlArr = url.split('/') | |||||
userName = urlArr.slice(-5)[0] | |||||
repoPath = urlArr.slice(-4)[0] | |||||
jobID = urlArr.slice(-1)[0] | |||||
}) | |||||
function stopBubbling(e) { | |||||
e = window.event || e; | |||||
if (e.stopPropagation) { | |||||
e.stopPropagation(); //阻止事件 冒泡传播 | |||||
} else { | |||||
e.cancelBubble = true; //ie兼容 | |||||
} | |||||
} | |||||
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) => { | |||||
$('input[name=end_line]').val(data.EndLine) | |||||
$('input[name=start_line]').val(data.StartLine) | |||||
$(`#log_file${version_name}`).text(data.Content) | |||||
document.getElementById("mask").style.display = "none" | |||||
}).fail(function (err) { | |||||
console.log(err); | |||||
document.getElementById("mask").style.display = "none" | |||||
}); | |||||
} | |||||
function loadModelFile(version_name, parents, filename, init) { | |||||
parents = parents || '' | |||||
filename = filename || '' | |||||
init = init || '' | |||||
console.log("start") | |||||
$.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/train-job/${jobID}/model_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | |||||
$(`#dir_list${version_name}`).empty() | |||||
renderDir(data, version_name) | |||||
if (init === "init") { | |||||
$(`input[name=model${version_name}]`).val("") | |||||
$(`input[name=modelback${version_name}]`).val(version_name) | |||||
$(`#file_breadcrumb${version_name}`).empty() | |||||
let htmlBread = "" | |||||
htmlBread += `<div class='active section'>${version_name}</div>` | |||||
htmlBread += "<div class='divider'> / </div>" | |||||
$(`#file_breadcrumb${version_name}`).append(htmlBread) | |||||
} else { | |||||
renderBrend(version_name, parents, filename, init) | |||||
} | |||||
}).fail(function (err) { | |||||
console.log(err, version_name); | |||||
}); | |||||
} | |||||
function renderBrend(version_name, parents, filename, init) { | |||||
if (init == "folder") { | |||||
let htmlBrend = "" | |||||
let sectionName = $(`#file_breadcrumb${version_name} .active.section`).text() | |||||
let parents1 = $(`input[name=model${version_name}]`).val() | |||||
let filename1 = $(`input[name=modelback${version_name}]`).val() | |||||
if (parents1 === "") { | |||||
$(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','','init')">${sectionName}</a>`) | |||||
} else { | |||||
$(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | |||||
} | |||||
htmlBrend += `<div class='active section'>${filename}</div>` | |||||
htmlBrend += "<div class='divider'> / </div>" | |||||
$(`#file_breadcrumb${version_name}`).append(htmlBrend) | |||||
$(`input[name=model${version_name}]`).val(parents) | |||||
$(`input[name=modelback${version_name}]`).val(filename) | |||||
} else { | |||||
$(`input[name=model${version_name}]`).val(parents) | |||||
$(`input[name=modelback${version_name}]`).val(filename) | |||||
$(`#file_breadcrumb${version_name} a.section:contains(${filename})`).nextAll().remove() | |||||
$(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | |||||
$(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | |||||
} | |||||
} | |||||
function renderDir(data, version_name) { | |||||
let html = "" | |||||
html += "<div class='ui grid' style='margin:0;'>" | |||||
html += "<div class='row' style='padding: 0;'>" | |||||
html += "<div class='ui sixteen wide column' style='padding:1rem;'>" | |||||
html += "<div class='dir list'>" | |||||
html += "<table id='repo-files-table' class='ui single line table pad20'>" | |||||
html += '<tbody>' | |||||
// html += "</tbody>" | |||||
for (let i = 0; i < data.Dirs.length; i++) { | |||||
let dirs_size = renderSize(data.Dirs[i].Size) | |||||
html += "<tr>" | |||||
html += "<td class='name six wid'>" | |||||
html += "<span class='truncate'>" | |||||
html += "<span class='octicon octicon-file-directory'>" | |||||
html += "</span>" | |||||
if (data.Dirs[i].IsDir) { | |||||
html += `<a onclick="loadModelFile('${version_name}','${data.Dirs[i].ParenDir}','${data.Dirs[i].FileName}','folder')">` | |||||
html += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | |||||
} else { | |||||
if (downlaodFlag) { | |||||
html += `<a href="${location.href}/download_model?version_name=${version_name}&fileName=${data.Dirs[i].FileName}&parentDir=${data.Dirs[i].ParenDir}&jobName=${realJobName}">` | |||||
} | |||||
else { | |||||
html += `<a class="disabled">` | |||||
} | |||||
html += "<span class='fitted'><i class='file icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | |||||
} | |||||
html += '</a>' | |||||
html += "</span>" | |||||
html += "</td>" | |||||
html += "<td class='message seven wide'>" | |||||
if (data.Dirs[i].IsDir) { | |||||
html += "<span class='truncate has-emoji'></span>" | |||||
} else { | |||||
html += "<span class='truncate has-emoji'>" + `${dirs_size}` + "</span>" | |||||
} | |||||
html += "</td>" | |||||
html += "<td class='text right age three wide'>" | |||||
html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | |||||
html += "</td>" | |||||
html += "</tr>" | |||||
} | |||||
html += "</tbody>" | |||||
html += "</table>" | |||||
html += "</div>" | |||||
html += "</div>" | |||||
html += "</div>" | |||||
html += "</div>" | |||||
$(`#dir_list${version_name}`).append(html) | |||||
} | |||||
function renderSize(value) { | |||||
if (null == value || value == '') { | |||||
return "0 Bytes"; | |||||
} | |||||
var unitArr = new Array("Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"); | |||||
var index = 0; | |||||
var srcsize = parseFloat(value); | |||||
index = Math.floor(Math.log(srcsize) / Math.log(1024)); | |||||
var size = srcsize / Math.pow(1024, index); | |||||
size = size.toFixed(0);//保留的小数位数 | |||||
return size + unitArr[index]; | |||||
} | |||||
function refreshStatus(version_name) { | |||||
$.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${taskID}?version_name=${versionname}`, (data) => { | |||||
// header status and duration | |||||
//$(`#${version_name}-duration-span`).text(data.JobDuration) | |||||
$(`#${version_name}-status-span span`).text(data.JobStatus) | |||||
$(`#${version_name}-status-span i`).attr("class", data.JobStatus) | |||||
// detail status and duration | |||||
//$('#'+version_name+'-duration').text(data.JobDuration) | |||||
$('#' + version_name + '-status').text(data.JobStatus) | |||||
loadLog(version_name) | |||||
}).fail(function (err) { | |||||
console.log(err); | |||||
}); | |||||
stopBubbling(arguments.callee.caller.arguments[0]) | |||||
} | |||||
function parseInfo() { | |||||
let jsonValue = document.getElementById("json_value").value; | |||||
let jsonObj = JSON.parse(jsonValue); | |||||
let podRoleName = jsonObj["podRoleName"]; | |||||
let html = ""; | |||||
if (podRoleName != null) { | |||||
let task0 = podRoleName["task1-0"]; | |||||
let podEvents = jsonObj["podEvents"]; | |||||
let podEventArray = podEvents[task0]; | |||||
if (podEventArray != null) { | |||||
for (var i = 0; i < podEventArray.length; i++) { | |||||
if (podEventArray[i]["reason"] != "") { | |||||
html += "<p><b>[" + podEventArray[i]["reason"] + "]</b></p>"; | |||||
html += "<p>" + podEventArray[i]["message"] + "</p>"; | |||||
html += "<p>" + podEventArray[i]["action"] + "</p>"; | |||||
} | |||||
} | |||||
} | |||||
let extras = jsonObj["extras"]; | |||||
if (extras != null) { | |||||
for (var i = 0; i < extras.length; i++) { | |||||
if (extras[i]["reason"] != "") { | |||||
html += "<p><b>[" + extras[i]["reason"] + "]</b></p>"; | |||||
html += "<p>" + extras[i]["message"] + "</p>"; | |||||
html += "<p>" + extras[i]["action"] + "</p>"; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
let string = document.getElementById("ExitDiagnostics").value; | |||||
string = string.replace(/\r\n/g, "<br>") | |||||
string = string.replace(/\n/g, "<br>"); | |||||
string = string.replace(/(\r\n)|(\n)/g, '<br>'); | |||||
if (string != "") { | |||||
html += "<p><b>[ExitDiagnostics]</b></p>"; | |||||
html += "<p>" + string + "</p>"; | |||||
} | |||||
document.getElementById("info_display").innerHTML = html; | |||||
} | |||||
</script> |
@@ -0,0 +1,475 @@ | |||||
{{template "base/head" .}} | |||||
<style> | |||||
.unite{ | |||||
font-family: SourceHanSansSC-medium !important; | |||||
color: rgba(16, 16, 16, 100) !important; | |||||
} | |||||
.title{ | |||||
font-size: 16px !important; | |||||
padding-left: 3rem !important; | |||||
} | |||||
.min_title{ | |||||
font-size: 14px !important; | |||||
padding-left: 6rem !important; | |||||
margin-bottom: 2rem !important; | |||||
} | |||||
.width{ | |||||
width:100% !important; | |||||
} | |||||
.width80{ | |||||
width: 80.7% !important; | |||||
margin-left: 10px; | |||||
} | |||||
.width85{ | |||||
width: 85% !important; | |||||
margin-left: 4.5rem !important; | |||||
} | |||||
.width81{ | |||||
margin-left: 1.5rem; | |||||
width: 81% !important; | |||||
} | |||||
.add{font-size: 18px; | |||||
padding: 0.5rem; | |||||
border: 1px solid rgba(187, 187, 187, 100); | |||||
border-radius: 0px 5px 5px 0px; | |||||
line-height: 21px; | |||||
text-align: center; | |||||
color: #C2C7CC; | |||||
} | |||||
.min{ | |||||
font-size: 18px; | |||||
padding: 0.5rem; | |||||
border: 1px solid rgba(187, 187, 187, 100); | |||||
border-radius: 5px 0px 0px 5px; | |||||
line-height: 21px; | |||||
text-align: center; | |||||
color: #C2C7CC; | |||||
} | |||||
</style> | |||||
<!-- <div class="ui page dimmer"> | |||||
<div class="ui text loader">{{.i18n.Tr "loading"}}</div> | |||||
</div> --> | |||||
<div id="mask"> | |||||
<div id="loadingPage"> | |||||
<div class="rect1"></div> | |||||
<div class="rect2"></div> | |||||
<div class="rect3"></div> | |||||
<div class="rect4"></div> | |||||
<div class="rect5"></div> | |||||
</div> | |||||
</div> | |||||
<div class="repository"> | |||||
{{template "repo/header" .}} | |||||
<div class="ui container"> | |||||
{{template "base/alert" .}} | |||||
<h4 class="ui top attached header"> | |||||
{{.i18n.Tr "repo.modelarts.train_job.new"}} | |||||
</h4> | |||||
<div class="ui attached segment"> | |||||
<!-- equal width --> | |||||
<form class="ui form" action="{{.Link}}" method="post"> | |||||
{{.CsrfTokenHtml}} | |||||
<input type="hidden" name="action" value="update"> | |||||
<input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
<input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
<div class="ui blue mini menu compact selectcloudbrain"> | |||||
<a class="item" href="{{.RepoLink}}/grampus/train-job/gpu/create"> | |||||
<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="{{.RepoLink}}/grampus/train-job/npu/create"> | |||||
<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 class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
</div> | |||||
<div class="unite min_title inline field"> | |||||
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||||
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
</div> | |||||
<div class="ui divider"></div> | |||||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | |||||
<div class="required unite min_title inline field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||||
<select class="ui dropdown width80 left2" id="code_version" name="branch_name"> | |||||
{{if .branch_name}} | |||||
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||||
{{range $k, $v :=.Branches}} | |||||
{{ if ne $v $.branch_name }} | |||||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
{{end}} | |||||
{{end}} | |||||
{{else}} | |||||
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||||
{{range $k, $v :=.Branches}} | |||||
{{ if ne $v $.branchName }} | |||||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||||
{{end}} | |||||
{{end}} | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="required unite min_title inline fields" style="width: 90%;"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}} </label> | |||||
<div class="field" style="flex: 1.5;"> | |||||
<select class="ui dropdown width" id="trainjob_engines" > | |||||
{{range .engines}} | |||||
<option value="{{.Value}}">{{.Value}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="field" style="flex: 2;" id="engine_name"> | |||||
<select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id"> | |||||
{{range .engine_versions}} | |||||
<option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
</div> | |||||
<div class="inline unite min_title field required"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
{{if .bootFile}} | |||||
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
{{else}} | |||||
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||||
{{end}} | |||||
<span> | |||||
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||||
</span> | |||||
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
</div> | |||||
{{template "custom/select_dataset_train" .}} | |||||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||||
<div class="inline unite min_title field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||||
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||||
<input id="store_run_para" type="hidden" name="run_para_list"> | |||||
<div class="dynamic field" style="margin-top: 1rem;"> | |||||
{{if ne 0 (len .params)}} | |||||
{{range $k ,$v := .params}} | |||||
<div class="two fields width85" id="para{{$k}}"> | |||||
<div class="field"> | |||||
<input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
</div> | |||||
<div class="field"> | |||||
<input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
</div> | |||||
<span> | |||||
<i class="trash icon"></i> | |||||
</span> | |||||
</div> | |||||
{{end}} | |||||
{{end}} | |||||
</div> | |||||
</div> | |||||
<div class="required field " style="display: none;"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | |||||
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | |||||
{{range .resource_pools}} | |||||
<option value="{{.ID}}">{{.Value}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="required grouped fields" style="display: none;"> | |||||
<label style="font-weight: normal;" for="resource_type">{{.i18n.Tr "repo.modelarts.train_job.resource_type"}}</label> | |||||
<div class="field"> | |||||
<div class="ui grid"> | |||||
<div class="column"> | |||||
<div class="ui radio checkbox"> | |||||
<input type="radio" name="resource_type" checked="" tabindex="0"> | |||||
</div> | |||||
</div> | |||||
<div class="three wide column">train-private-1</div> | |||||
<div class="three wide column">{{svg "octicon-verified" 16}} 运行中</div> | |||||
<div class="three wide column"> CPU:192 核 2048GiB</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="required unite min_title inline field" id="flaver_name"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||||
<select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | |||||
{{range .flavor_infos}} | |||||
<option name="flavor" value="{{.Code}}">{{.Value}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | |||||
<div class="inline required unite min_title field"> | |||||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||||
<div class="ui labeled input" style="width: 5%;"> | |||||
<input style="border-radius: 0;text-align: center;"type="hidden" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | |||||
<div class="field" id="trainjob_work_server_num_select" name="work_server_number_select"> | |||||
<select class="ui dropdown width" style='width: 100%;' name="work_server_id"> | |||||
<option name="server_id" value="1">1</option> | |||||
<option name="server_id" value="2">2</option> | |||||
</select> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="inline unite min_title field"> | |||||
<button class="ui create_train_job green button"> | |||||
{{.i18n.Tr "repo.cloudbrain.new"}} | |||||
</button> | |||||
<a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||||
</div> | |||||
<!-- 模态框 --> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} | |||||
<script> | |||||
let url_href = window.location.pathname.split('create')[0] | |||||
$(".ui.button").attr('href',url_href) | |||||
$('select.dropdown') | |||||
.dropdown(); | |||||
$('.menu .item') | |||||
.tab(); | |||||
// 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){ | |||||
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"}}> ' + | |||||
'</div> ' + | |||||
'<div class="field"> ' + | |||||
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
'</div>'+ | |||||
'<span>' + | |||||
'<i class="trash icon">' + | |||||
'</i>' + | |||||
'</span>' + | |||||
'</div>' | |||||
$(".dynamic.field").append(value) | |||||
} | |||||
$('#add_run_para').click(function(){ | |||||
var len = $(".dynamic.field .two.fields").length | |||||
Add_parameter(len) | |||||
}); | |||||
$(".dynamic.field").on("click",".trash.icon", function() { | |||||
var index = $(this).parent().parent().index() | |||||
$(this).parent().parent().remove() | |||||
var len = $(".dynamic.field .two.fields").length | |||||
$(".dynamic.field .two.fields").each(function(){ | |||||
var cur_index = $(this).index() | |||||
$(this).attr('id', 'para' + cur_index) | |||||
}) | |||||
}); | |||||
$('.ui.parameter.green.button').click(function(){ | |||||
var parameters = []; | |||||
$('table tr').each(function() { | |||||
$(this).find('td:eq(1)').each(function(){ | |||||
parameters.push($(this).text()); | |||||
}) | |||||
$(this).find('input').each(function(){ | |||||
parameters.push($(this).text()) | |||||
}) | |||||
}); | |||||
$('.ui.parameter.modal') | |||||
.modal('hide'); | |||||
for(var i = 2; i < parameters.length; i++){ | |||||
switch(i) { | |||||
// 数据集uuid待完成 | |||||
// case (2): | |||||
// console.log(1) | |||||
// break; | |||||
// $("#trainjob_datasets").val(parameters[i]); | |||||
// console.log($("#trainjob_datasets").val()) | |||||
case (3): | |||||
$("input[name='boot_file']").val(parameters[i]); | |||||
break; | |||||
case (4): | |||||
var para = parameters[i].split(" ") | |||||
for(var j = 0; j < para.length; j++){ | |||||
var para_name = para[j].split('=')[0] | |||||
var para_value = para[j].split('=')[1] | |||||
var len = $(".dynamic.field .two.fields").length | |||||
Add_parameter(len) | |||||
var pid = 'para' + len | |||||
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
} | |||||
break; | |||||
// 数据集pool_id待完成 | |||||
// case (5): | |||||
// $("select[name='pool_id']").val(parameters[i]); | |||||
// break; | |||||
case (6): | |||||
// $("input[name='work_server_number']").val(parameters[i]); | |||||
break; | |||||
} | |||||
} | |||||
}) | |||||
$('.ui.save.checkbox').click(function(){ | |||||
$(this).checkbox({ | |||||
onChange: function(){ | |||||
if ($('.ui.save.checkbox').checkbox('is checked')){ | |||||
$('#save_para').removeClass("disabled") | |||||
}else{ | |||||
$('#save_para').addClass("disabled") | |||||
} | |||||
} | |||||
}); | |||||
}) | |||||
$('.question.circle.icon').hover(function(){ | |||||
$(this).popup('show') | |||||
}); | |||||
$(".item.active.parameter_config").click(function(){ | |||||
$('.ui.parameter.modal') | |||||
.modal('setting', 'closable', false) | |||||
.modal('show'); | |||||
}) | |||||
$('.ui.deny.button').click(function(){ | |||||
$('.ui.parameter.modal') | |||||
.modal('hide'); | |||||
}) | |||||
$('select.dropdown') | |||||
.dropdown(); | |||||
function validate(){ | |||||
$('.ui.form') | |||||
.form({ | |||||
on: 'blur', | |||||
fields: { | |||||
boot_file: { | |||||
identifier : 'boot_file', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/.+\.py$/g]', | |||||
} | |||||
] | |||||
}, | |||||
display_job_name:{ | |||||
identifier : 'display_job_name', | |||||
rules: [ | |||||
{ | |||||
type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
} | |||||
] | |||||
}, | |||||
attachment:{ | |||||
identifier : 'attachment', | |||||
rules: [ | |||||
{ | |||||
type: 'empty', | |||||
} | |||||
] | |||||
}, | |||||
work_server_number: { | |||||
identifier : 'work_server_number', | |||||
rules: [ | |||||
{ | |||||
type : 'integer[1..25]', | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
onSuccess: function(){ | |||||
// $('.ui.page.dimmer').dimmer('show') | |||||
document.getElementById("mask").style.display = "block" | |||||
}, | |||||
onFailure: function(e){ | |||||
return false; | |||||
} | |||||
}) | |||||
} | |||||
document.onreadystatechange = function() { | |||||
if (document.readyState === "complete") { | |||||
document.getElementById("mask").style.display = "none" | |||||
} | |||||
} | |||||
function send_run_para(){ | |||||
var run_parameters = [] | |||||
var msg = {} | |||||
$(".dynamic.field .two.fields").each(function(){ | |||||
var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
run_parameters.push({"label": para_name, "value": para_value}) | |||||
}) | |||||
msg["parameter"] = run_parameters | |||||
msg = JSON.stringify(msg) | |||||
$('#store_run_para').val(msg) | |||||
} | |||||
function get_name(){ | |||||
let name1=$("#engine_name .text").text() | |||||
let name2=$("#flaver_name .text").text() | |||||
$("input#ai_engine_name").val(name1) | |||||
$("input#ai_flaver_name").val(name2) | |||||
let val_server_num_select = $("#trainjob_work_server_num_select .text").text() | |||||
// console.log("val_server_num_select:",val_server_num_select) | |||||
$("input#trainjob_work_server_num").val(val_server_num_select) | |||||
} | |||||
$('.ui.create_train_job.green.button').click(function(e) { | |||||
get_name() | |||||
send_run_para() | |||||
validate() | |||||
}) | |||||
</script> |