You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

resource_specification.go 16 kB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. package models
  2. import (
  3. "code.gitea.io/gitea/modules/timeutil"
  4. "fmt"
  5. "xorm.io/builder"
  6. )
  7. const (
  8. SpecNotVerified int = iota + 1
  9. SpecOnShelf
  10. SpecOffShelf
  11. )
  12. type SearchSpecOrderBy int
  13. const (
  14. SearchSpecOrderById SearchSpecOrderBy = iota
  15. SearchSpecOrder4Standard
  16. )
  17. type ResourceSpecification struct {
  18. ID int64 `xorm:"pk autoincr"`
  19. QueueId int64 `xorm:"INDEX"`
  20. SourceSpecId string `xorm:"INDEX"`
  21. AccCardsNum int
  22. CpuCores int
  23. MemGiB float32
  24. GPUMemGiB float32
  25. ShareMemGiB float32
  26. UnitPrice int
  27. Status int
  28. IsAvailable bool
  29. IsAutomaticSync bool
  30. CreatedTime timeutil.TimeStamp `xorm:"created"`
  31. CreatedBy int64
  32. UpdatedTime timeutil.TimeStamp `xorm:"updated"`
  33. UpdatedBy int64
  34. }
  35. func (r ResourceSpecification) ConvertToRes() *ResourceSpecificationRes {
  36. return &ResourceSpecificationRes{
  37. ID: r.ID,
  38. SourceSpecId: r.SourceSpecId,
  39. AccCardsNum: r.AccCardsNum,
  40. CpuCores: r.CpuCores,
  41. MemGiB: r.MemGiB,
  42. ShareMemGiB: r.ShareMemGiB,
  43. GPUMemGiB: r.GPUMemGiB,
  44. UnitPrice: r.UnitPrice,
  45. Status: r.Status,
  46. IsAvailable: r.IsAvailable,
  47. UpdatedTime: r.UpdatedTime,
  48. }
  49. }
  50. type ResourceSpecificationReq struct {
  51. QueueId int64 `binding:"Required"`
  52. SourceSpecId string
  53. AccCardsNum int
  54. CpuCores int
  55. MemGiB float32
  56. GPUMemGiB float32
  57. ShareMemGiB float32
  58. UnitPrice int
  59. Status int
  60. IsAutomaticSync bool
  61. CreatorId int64
  62. }
  63. func (r ResourceSpecificationReq) ToDTO() ResourceSpecification {
  64. return ResourceSpecification{
  65. QueueId: r.QueueId,
  66. SourceSpecId: r.SourceSpecId,
  67. AccCardsNum: r.AccCardsNum,
  68. CpuCores: r.CpuCores,
  69. MemGiB: r.MemGiB,
  70. GPUMemGiB: r.GPUMemGiB,
  71. ShareMemGiB: r.ShareMemGiB,
  72. UnitPrice: r.UnitPrice,
  73. Status: r.Status,
  74. IsAutomaticSync: r.IsAutomaticSync,
  75. CreatedBy: r.CreatorId,
  76. UpdatedBy: r.CreatorId,
  77. IsAvailable: true,
  78. }
  79. }
  80. type SearchResourceSpecificationOptions struct {
  81. ListOptions
  82. QueueId int64
  83. Status int
  84. Cluster string
  85. AvailableCode int
  86. OrderBy SearchSpecOrderBy
  87. }
  88. type SearchResourceBriefSpecificationOptions struct {
  89. QueueId int64
  90. Cluster string
  91. }
  92. type ResourceSpecAndQueueListRes struct {
  93. TotalSize int64
  94. List []*ResourceSpecAndQueueRes
  95. }
  96. func NewResourceSpecAndQueueListRes(totalSize int64, list []ResourceSpecAndQueue) *ResourceSpecAndQueueListRes {
  97. resList := make([]*ResourceSpecAndQueueRes, len(list))
  98. for i, v := range list {
  99. resList[i] = v.ConvertToRes()
  100. }
  101. return &ResourceSpecAndQueueListRes{
  102. TotalSize: totalSize,
  103. List: resList,
  104. }
  105. }
  106. type ResourceSpecificationRes struct {
  107. ID int64
  108. SourceSpecId string
  109. AccCardsNum int
  110. CpuCores int
  111. MemGiB float32
  112. GPUMemGiB float32
  113. ShareMemGiB float32
  114. UnitPrice int
  115. Status int
  116. IsAvailable bool
  117. UpdatedTime timeutil.TimeStamp
  118. }
  119. func (ResourceSpecificationRes) TableName() string {
  120. return "resource_specification"
  121. }
  122. type ResourceSpecAndQueueRes struct {
  123. Spec *ResourceSpecificationRes
  124. Queue *ResourceQueueRes
  125. }
  126. type ResourceSpecAndQueue struct {
  127. ResourceSpecification `xorm:"extends"`
  128. ResourceQueue `xorm:"extends"`
  129. }
  130. func (*ResourceSpecAndQueue) TableName() string {
  131. return "resource_specification"
  132. }
  133. func (r ResourceSpecAndQueue) ConvertToRes() *ResourceSpecAndQueueRes {
  134. return &ResourceSpecAndQueueRes{
  135. Spec: r.ResourceSpecification.ConvertToRes(),
  136. Queue: r.ResourceQueue.ConvertToRes(),
  137. }
  138. }
  139. type FindSpecsOptions struct {
  140. JobType JobType
  141. ComputeResource string
  142. Cluster string
  143. AiCenterCode string
  144. SpecId int64
  145. QueueCode string
  146. SourceSpecId string
  147. AccCardsNum int
  148. UseAccCardsNum bool
  149. AccCardType string
  150. CpuCores int
  151. UseCpuCores bool
  152. MemGiB float32
  153. UseMemGiB bool
  154. GPUMemGiB float32
  155. UseGPUMemGiB bool
  156. ShareMemGiB float32
  157. UseShareMemGiB bool
  158. //if true,find specs no matter used or not used in scene. if false,only find specs used in scene
  159. RequestAll bool
  160. SpecStatus int
  161. }
  162. type Specification struct {
  163. ID int64
  164. SourceSpecId string
  165. AccCardsNum int
  166. AccCardType string
  167. CpuCores int
  168. MemGiB float32
  169. GPUMemGiB float32
  170. ShareMemGiB float32
  171. ComputeResource string
  172. UnitPrice int
  173. QueueId int64
  174. QueueCode string
  175. Cluster string
  176. AiCenterCode string
  177. AiCenterName string
  178. IsExclusive bool
  179. ExclusiveOrg string
  180. }
  181. func (Specification) TableName() string {
  182. return "resource_specification"
  183. }
  184. func InsertResourceSpecification(r ResourceSpecification) (int64, error) {
  185. return x.Insert(&r)
  186. }
  187. func UpdateResourceSpecificationById(queueId int64, spec ResourceSpecification) (int64, error) {
  188. return x.ID(queueId).Update(&spec)
  189. }
  190. func UpdateSpecUnitPriceById(id int64, unitPrice int) error {
  191. _, err := x.Exec("update resource_specification set unit_price = ? ,updated_time = ? where id = ?", unitPrice, timeutil.TimeStampNow(), id)
  192. return err
  193. }
  194. func SearchResourceSpecification(opts SearchResourceSpecificationOptions) (int64, []ResourceSpecAndQueue, error) {
  195. var cond = builder.NewCond()
  196. if opts.Page <= 0 {
  197. opts.Page = 1
  198. }
  199. if opts.QueueId > 0 {
  200. cond = cond.And(builder.Eq{"resource_specification.queue_id": opts.QueueId})
  201. }
  202. if opts.Status > 0 {
  203. cond = cond.And(builder.Eq{"resource_specification.status": opts.Status})
  204. }
  205. if opts.Cluster != "" {
  206. cond = cond.And(builder.Eq{"resource_queue.cluster": opts.Cluster})
  207. }
  208. if opts.AvailableCode == 1 {
  209. cond = cond.And(builder.Eq{"resource_specification.is_available": true})
  210. } else if opts.AvailableCode == 2 {
  211. cond = cond.And(builder.Eq{"resource_specification.is_available": false})
  212. }
  213. //cond = cond.And(builder.Or(builder.Eq{"resource_queue.deleted_time": 0}).Or(builder.IsNull{"resource_queue.deleted_time"}))
  214. n, err := x.Where(cond).Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id").
  215. Unscoped().Count(&ResourceSpecAndQueue{})
  216. if err != nil {
  217. return 0, nil, err
  218. }
  219. var orderby = ""
  220. switch opts.OrderBy {
  221. case SearchSpecOrder4Standard:
  222. orderby = "resource_queue.compute_resource asc,resource_queue.acc_card_type asc,resource_specification.acc_cards_num asc,resource_specification.cpu_cores asc,resource_specification.mem_gi_b asc,resource_specification.share_mem_gi_b asc"
  223. default:
  224. orderby = "resource_specification.id desc"
  225. }
  226. r := make([]ResourceSpecAndQueue, 0)
  227. err = x.Where(cond).
  228. Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id").
  229. OrderBy(orderby).
  230. Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
  231. Unscoped().Find(&r)
  232. if err != nil {
  233. return 0, nil, err
  234. }
  235. return n, r, nil
  236. }
  237. func GetSpecScenes(specId int64) ([]ResourceSceneBriefRes, error) {
  238. r := make([]ResourceSceneBriefRes, 0)
  239. err := x.Where("resource_scene_spec.spec_id = ?", specId).
  240. Join("INNER", "resource_scene_spec", "resource_scene_spec.scene_id = resource_scene.id").
  241. Find(&r)
  242. if err != nil {
  243. return nil, err
  244. }
  245. return r, nil
  246. }
  247. func ResourceSpecOnShelf(id int64, unitPrice int) error {
  248. _, err := x.Exec("update resource_specification set unit_price = ?,updated_time = ?,status = ? where id = ?", unitPrice, timeutil.TimeStampNow(), SpecOnShelf, id)
  249. return err
  250. }
  251. func ResourceSpecOffShelf(id int64) (int64, error) {
  252. sess := x.NewSession()
  253. var err error
  254. defer func() {
  255. if err != nil {
  256. sess.Rollback()
  257. }
  258. sess.Close()
  259. }()
  260. param := ResourceSpecification{
  261. Status: SpecOffShelf,
  262. }
  263. n, err := sess.Where("id = ? and status = ?", id, SpecOnShelf).Update(&param)
  264. if err != nil {
  265. return 0, err
  266. }
  267. sess.Commit()
  268. return n, err
  269. }
  270. func GetResourceSpecification(r *ResourceSpecification) (*ResourceSpecification, error) {
  271. has, err := x.Get(r)
  272. if err != nil {
  273. return nil, err
  274. } else if !has {
  275. return nil, nil
  276. }
  277. return r, nil
  278. }
  279. func SyncGrampusSpecs(updateList []ResourceSpecification, insertList []ResourceSpecification, existIds []int64) error {
  280. sess := x.NewSession()
  281. var err error
  282. defer func() {
  283. if err != nil {
  284. sess.Rollback()
  285. }
  286. sess.Close()
  287. }()
  288. //delete specs and scene that no longer exists
  289. deleteIds := make([]int64, 0)
  290. cond := builder.NewCond()
  291. cond = cond.And(builder.NotIn("resource_specification.id", existIds)).And(builder.Eq{"resource_queue.cluster": C2NetCluster})
  292. if err := sess.Cols("resource_specification.id").Table("resource_specification").
  293. Where(cond).Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id").
  294. Find(&deleteIds); err != nil {
  295. return err
  296. }
  297. if len(deleteIds) > 0 {
  298. if _, err = sess.Cols("status", "is_available").In("id", deleteIds).Update(&ResourceSpecification{Status: SpecOffShelf, IsAvailable: false}); err != nil {
  299. return err
  300. }
  301. }
  302. //update exists specs
  303. if len(updateList) > 0 {
  304. for _, v := range updateList {
  305. if _, err = sess.ID(v.ID).UseBool("is_available").Update(&v); err != nil {
  306. return err
  307. }
  308. }
  309. }
  310. //insert new specs
  311. if len(insertList) > 0 {
  312. if _, err = sess.Insert(insertList); err != nil {
  313. return err
  314. }
  315. }
  316. return sess.Commit()
  317. }
  318. //FindSpecs
  319. func FindSpecs(opts FindSpecsOptions) ([]*Specification, error) {
  320. var cond = builder.NewCond()
  321. if !opts.RequestAll && opts.JobType != "" {
  322. cond = cond.And(builder.Eq{"resource_scene.job_type": opts.JobType})
  323. }
  324. if opts.ComputeResource != "" {
  325. cond = cond.And(builder.Eq{"resource_queue.compute_resource": opts.ComputeResource})
  326. }
  327. if opts.Cluster != "" {
  328. cond = cond.And(builder.Eq{"resource_queue.cluster": opts.Cluster})
  329. }
  330. if opts.AiCenterCode != "" {
  331. cond = cond.And(builder.Eq{"resource_queue.ai_center_code": opts.AiCenterCode})
  332. }
  333. if opts.SpecId > 0 {
  334. cond = cond.And(builder.Eq{"resource_specification.id": opts.SpecId})
  335. }
  336. if opts.QueueCode != "" {
  337. cond = cond.And(builder.Eq{"resource_queue.queue_code": opts.QueueCode})
  338. }
  339. if opts.SourceSpecId != "" {
  340. cond = cond.And(builder.Eq{"resource_specification.source_spec_id": opts.SourceSpecId})
  341. }
  342. if opts.UseAccCardsNum {
  343. cond = cond.And(builder.Eq{"resource_specification.acc_cards_num": opts.AccCardsNum})
  344. }
  345. if opts.AccCardType != "" {
  346. cond = cond.And(builder.Eq{"resource_queue.acc_card_type": opts.AccCardType})
  347. }
  348. if opts.UseCpuCores {
  349. cond = cond.And(builder.Eq{"resource_specification.cpu_cores": opts.CpuCores})
  350. }
  351. if opts.UseMemGiB {
  352. cond = cond.And(builder.Eq{"resource_specification.mem_gi_b": opts.MemGiB})
  353. }
  354. if opts.UseGPUMemGiB {
  355. cond = cond.And(builder.Eq{"resource_specification.gpu_mem_gi_b": opts.GPUMemGiB})
  356. }
  357. if opts.UseShareMemGiB {
  358. cond = cond.And(builder.Eq{"resource_specification.share_mem_gi_b": opts.ShareMemGiB})
  359. }
  360. if opts.SpecStatus > 0 {
  361. cond = cond.And(builder.Eq{"resource_specification.status": opts.SpecStatus})
  362. }
  363. r := make([]*Specification, 0)
  364. s := x.Where(cond).
  365. Join("INNER", "resource_queue", "resource_queue.id = resource_specification.queue_id")
  366. if !opts.RequestAll {
  367. s = s.Join("INNER", "resource_scene_spec", "resource_scene_spec.spec_id = resource_specification.id").
  368. Join("INNER", "resource_scene", "resource_scene_spec.scene_id = resource_scene.id")
  369. }
  370. err := s.OrderBy("resource_queue.compute_resource asc,resource_queue.acc_card_type asc,resource_specification.acc_cards_num asc,resource_specification.cpu_cores asc,resource_specification.mem_gi_b asc,resource_specification.share_mem_gi_b asc").
  371. Unscoped().Find(&r)
  372. if err != nil {
  373. return nil, err
  374. }
  375. return r, nil
  376. }
  377. func InitQueueAndSpec(queue ResourceQueue, spec ResourceSpecification) (*Specification, error) {
  378. sess := x.NewSession()
  379. defer sess.Close()
  380. sess.Begin()
  381. param := ResourceQueue{
  382. QueueCode: queue.QueueCode,
  383. Cluster: queue.Cluster,
  384. AiCenterCode: queue.AiCenterCode,
  385. ComputeResource: queue.ComputeResource,
  386. AccCardType: queue.AccCardType,
  387. }
  388. _, err := sess.Get(&param)
  389. if err != nil {
  390. sess.Rollback()
  391. return nil, err
  392. }
  393. if param.ID == 0 {
  394. _, err = sess.InsertOne(&queue)
  395. if err != nil {
  396. sess.Rollback()
  397. return nil, err
  398. }
  399. } else {
  400. queue = param
  401. }
  402. spec.QueueId = queue.ID
  403. _, err = sess.InsertOne(&spec)
  404. if err != nil {
  405. sess.Rollback()
  406. return nil, err
  407. }
  408. sess.Commit()
  409. return BuildSpecification(queue, spec), nil
  410. }
  411. func BuildSpecification(queue ResourceQueue, spec ResourceSpecification) *Specification {
  412. return &Specification{
  413. ID: spec.ID,
  414. SourceSpecId: spec.SourceSpecId,
  415. AccCardsNum: spec.AccCardsNum,
  416. AccCardType: queue.AccCardType,
  417. CpuCores: spec.CpuCores,
  418. MemGiB: spec.MemGiB,
  419. GPUMemGiB: spec.GPUMemGiB,
  420. ShareMemGiB: spec.ShareMemGiB,
  421. ComputeResource: queue.ComputeResource,
  422. UnitPrice: spec.UnitPrice,
  423. QueueId: queue.ID,
  424. QueueCode: queue.QueueCode,
  425. Cluster: queue.Cluster,
  426. AiCenterCode: queue.AiCenterCode,
  427. AiCenterName: queue.AiCenterName,
  428. }
  429. }
  430. func GetCloudbrainOneAccCardType(queueCode string) string {
  431. switch queueCode {
  432. case "a100":
  433. return "A100"
  434. case "openidebug":
  435. return "T4"
  436. case "openidgx":
  437. return "V100"
  438. }
  439. return ""
  440. }
  441. var cloudbrainTwoSpecsInitFlag = false
  442. var cloudbrainTwoSpecs map[string]*Specification
  443. func GetCloudbrainTwoSpecs() (map[string]*Specification, error) {
  444. if !cloudbrainTwoSpecsInitFlag {
  445. r, err := InitCloudbrainTwoSpecs()
  446. if err != nil {
  447. return nil, err
  448. }
  449. cloudbrainTwoSpecsInitFlag = true
  450. cloudbrainTwoSpecs = r
  451. }
  452. return cloudbrainTwoSpecs, nil
  453. }
  454. func InitCloudbrainTwoSpecs() (map[string]*Specification, error) {
  455. r := make(map[string]*Specification, 0)
  456. queue, err := GetResourceQueue(&ResourceQueue{QueueCode: "openisupport"})
  457. if err != nil {
  458. return nil, err
  459. }
  460. if queue == nil {
  461. queue = &ResourceQueue{
  462. QueueCode: "openisupport",
  463. Cluster: OpenICluster,
  464. AiCenterCode: AICenterOfCloudBrainTwo,
  465. AiCenterName: "云脑二",
  466. ComputeResource: NPU,
  467. AccCardType: "ASCEND910",
  468. Remark: "处理历史云脑任务时自动生成",
  469. }
  470. _, err = x.InsertOne(queue)
  471. if err != nil {
  472. return nil, err
  473. }
  474. }
  475. for i := 1; i <= 8; i = i * 2 {
  476. sourceSpecId := "modelarts.bm.910.arm.public." + fmt.Sprint(i)
  477. spec, err := GetResourceSpecification(&ResourceSpecification{
  478. SourceSpecId: sourceSpecId,
  479. QueueId: queue.ID,
  480. })
  481. if err != nil {
  482. return nil, err
  483. }
  484. if spec == nil {
  485. spec = &ResourceSpecification{
  486. QueueId: queue.ID,
  487. SourceSpecId: sourceSpecId,
  488. AccCardsNum: i,
  489. CpuCores: i * 24,
  490. MemGiB: float32(i * 256),
  491. GPUMemGiB: float32(32),
  492. Status: SpecOffShelf,
  493. IsAvailable: true,
  494. }
  495. _, err = x.Insert(spec)
  496. if err != nil {
  497. return nil, err
  498. }
  499. }
  500. r[sourceSpecId] = BuildSpecification(*queue, *spec)
  501. }
  502. return r, nil
  503. }
  504. var grampusSpecsInitFlag = false
  505. var grampusSpecs map[string]*Specification
  506. func GetGrampusSpecs() (map[string]*Specification, error) {
  507. if !grampusSpecsInitFlag {
  508. specMap := make(map[string]*Specification, 0)
  509. r, err := FindSpecs(FindSpecsOptions{
  510. Cluster: C2NetCluster,
  511. RequestAll: true,
  512. })
  513. if err != nil {
  514. return nil, err
  515. }
  516. for _, spec := range r {
  517. specMap[spec.SourceSpecId] = spec
  518. specMap[spec.SourceSpecId+"_"+spec.AiCenterCode] = spec
  519. }
  520. grampusSpecsInitFlag = true
  521. grampusSpecs = specMap
  522. }
  523. return grampusSpecs, nil
  524. }