@platforma-sdk/workflow-tengo 6.8.3 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/tengo/lib/exec.constants.lib.tengo +2 -0
  2. package/dist/tengo/lib/exec.delayed-compute-allocation.lib.tengo +5 -1
  3. package/dist/tengo/lib/exec.formula.lib.tengo +13 -1
  4. package/dist/tengo/lib/exec.lib.tengo +80 -4
  5. package/dist/tengo/lib/exec.limits.lib.tengo +28 -0
  6. package/dist/tengo/lib/feats.lib.tengo +5 -0
  7. package/dist/tengo/tpl/annotations.compute.plj.gz +0 -0
  8. package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
  9. package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
  10. package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
  11. package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
  12. package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
  13. package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
  14. package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
  15. package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
  16. package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
  17. package/dist/tengo/tpl/exec.conda.create-env.plj.gz +0 -0
  18. package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
  19. package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
  20. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  21. package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
  22. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  23. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  24. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  25. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  26. package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
  27. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  28. package/dist/tengo/tpl/pframes.build-table.plj.gz +0 -0
  29. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  30. package/dist/tengo/tpl/pframes.export-parquet-pcolumn-chunk.plj.gz +0 -0
  31. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  32. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.merge-resource-maps.plj.gz +0 -0
  36. package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
  37. package/dist/tengo/tpl/pframes.process-pcolumn-batch-split.plj.gz +0 -0
  38. package/dist/tengo/tpl/pframes.process-pcolumn-batch.plj.gz +0 -0
  39. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  40. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  41. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  42. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  43. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  44. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  45. package/dist/tengo/tpl/pt.import-dir.plj.gz +0 -0
  46. package/dist/tengo/tpl/pt.workflow-run.plj.gz +0 -0
  47. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  48. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  49. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  50. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  51. package/dist/tengo/tpl/workflow.query-context-filter.plj.gz +0 -0
  52. package/package.json +4 -4
@@ -28,6 +28,7 @@ RUNNER_EXECUTOR := "executor" // local binary execution
28
28
  META_INPUT_MEM_FORMULA := "__memFormula__"
29
29
  META_INPUT_CPU_FORMULA := "__cpuFormula__"
30
30
  META_INPUT_GPU_FORMULA := "__gpuFormula__"
31
+ META_INPUT_SCRATCH_FORMULA := "__scratchFormula__"
31
32
  REGULAR_INPUT_LINE_COUNT := "__metric_lineCount__"
32
33
 
33
34
  export ll.toStrict({
@@ -49,5 +50,6 @@ export ll.toStrict({
49
50
  META_INPUT_MEM_FORMULA: META_INPUT_MEM_FORMULA,
50
51
  META_INPUT_CPU_FORMULA: META_INPUT_CPU_FORMULA,
51
52
  META_INPUT_GPU_FORMULA: META_INPUT_GPU_FORMULA,
53
+ META_INPUT_SCRATCH_FORMULA: META_INPUT_SCRATCH_FORMULA,
52
54
  REGULAR_INPUT_LINE_COUNT: REGULAR_INPUT_LINE_COUNT
53
55
  })
@@ -22,7 +22,8 @@ create := func(workdir, req) {
22
22
  "queue": "string",
23
23
  "cpu,?": "number",
24
24
  "ram,?": ["or", "number", "string"],
25
- "gpuMemory,?": "string"
25
+ "gpuMemory,?": "string",
26
+ "scratchFreeSpace,?": ["or", "number", "string"]
26
27
  }, "request must be a valid request")
27
28
 
28
29
  reqMap := { queue: req.queue }
@@ -35,6 +36,9 @@ create := func(workdir, req) {
35
36
  if !is_undefined(req.gpuMemory) {
36
37
  reqMap.gpuMemory = req.gpuMemory
37
38
  }
39
+ if !is_undefined(req.scratchFreeSpace) {
40
+ reqMap.scratchFreeSpace = req.scratchFreeSpace
41
+ }
38
42
 
39
43
  delayedComputeAllocation := render.createEphemeral(tpl, {
40
44
  request: smart.createJsonResource(reqMap),
@@ -298,12 +298,21 @@ referencedMetricFiles := func(resolvedNode) {
298
298
 
299
299
 
300
300
 
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
301
309
 
302
310
 
303
311
 
304
312
  applyFormulaFallback := func(dims) {
305
313
  gpu := is_undefined(dims.gpu) ? {} : dims.gpu
306
- res := { ram: dims.ram.static, cpu: dims.cpu.static, gpu: gpu.static, err: undefined }
314
+ scratch := is_undefined(dims.scratch) ? {} : dims.scratch
315
+ res := { ram: dims.ram.static, cpu: dims.cpu.static, gpu: gpu.static, scratch: scratch.static, err: undefined }
307
316
  if !is_undefined(_unwrap(dims.ram.ast)) && is_undefined(res.ram) {
308
317
  if is_undefined(dims.ram.fallback) {
309
318
  res.err = "exec.builder: the RAM formula needs a static fallback on backends that can't evaluate resource formulas at run time. Provide .staticFallback(...) on the RAM formula, set a static ram, or upgrade the backend."
@@ -325,6 +334,9 @@ applyFormulaFallback := func(dims) {
325
334
  }
326
335
  res.gpu = gpu.fallback
327
336
  }
337
+ if !is_undefined(_unwrap(scratch.ast)) && is_undefined(res.scratch) {
338
+ res.scratch = scratch.fallback
339
+ }
328
340
  return res
329
341
  }
330
342
 
@@ -61,6 +61,12 @@ _assertValidGpuRequest := func(amount, ctx) {
61
61
  }
62
62
 
63
63
 
64
+ _assertValidScratchRequest := func(amount, ctx) {
65
+ validation.assertType(amount, ["or", "number", "string"], ctx + ": scratch space amount must be a number of bytes or a size string like '500GiB'")
66
+ ll.assert(is_string(amount) || amount >= 16 * units.MiB, ctx + ": scratch space in bytes should be at least 16MiB (did you pass bytes instead of GiB?)")
67
+ }
68
+
69
+
64
70
 
65
71
 
66
72
 
@@ -92,6 +98,7 @@ builder := func() {
92
98
  cpuRequest := undefined
93
99
  ramRequest := undefined
94
100
  gpuMemory := undefined
101
+ scratchFreeSpace := undefined
95
102
 
96
103
 
97
104
 
@@ -103,6 +110,8 @@ builder := func() {
103
110
  cpuFormulaFallback := undefined
104
111
  gpuFormulaAst := undefined
105
112
  gpuFormulaFallback := undefined
113
+ scratchFormulaAst := undefined
114
+ scratchFormulaFallback := undefined
106
115
  fileTags := {} // fileName -> tag (for f.size("tag") / f.lineCount("tag") aggregation)
107
116
 
108
117
  commandName := ""
@@ -520,6 +529,27 @@ builder := func() {
520
529
 
521
530
 
522
531
 
532
+
533
+
534
+
535
+
536
+
537
+
538
+
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+
551
+
552
+
523
553
 
524
554
 
525
555
 
@@ -592,6 +622,20 @@ builder := func() {
592
622
  memFormulaFallback = undefined
593
623
  }
594
624
  }
625
+ setScratch := func(v, ctx) {
626
+ if execFormula.isFormula(v) {
627
+ scratchFormulaAst = execFormula.astOf(v)
628
+ scratchFormulaFallback = undefined
629
+ fb := execFormula.fallbackOf(v)
630
+ if !is_undefined(fb) { _assertValidScratchRequest(fb, ctx + " scratchFreeSpace fallback"); scratchFormulaFallback = fb }
631
+ scratchFreeSpace = undefined
632
+ } else {
633
+ _assertValidScratchRequest(v, ctx + " scratchFreeSpace")
634
+ scratchFreeSpace = v
635
+ scratchFormulaAst = undefined
636
+ scratchFormulaFallback = undefined
637
+ }
638
+ }
595
639
  setVram := func(v, ctx) {
596
640
  if execFormula.isFormula(v) {
597
641
  gpuFormulaAst = execFormula.astOf(v)
@@ -610,8 +654,8 @@ builder := func() {
610
654
  assertKeys := func(block, name, allowVram) {
611
655
  ll.assert(ll.isMap(block), "exec.builder.resources.%s: expected a map", name)
612
656
  for k, _ in block {
613
- ok := k == "cpu" || k == "ram" || (allowVram && k == "vram")
614
- ll.assert(ok, "exec.builder.resources.%s: unknown key %q (allowed: %s)", name, k, allowVram ? "cpu, ram, vram" : "cpu, ram")
657
+ ok := k == "cpu" || k == "ram" || k == "scratchFreeSpace" || (allowVram && k == "vram")
658
+ ll.assert(ok, "exec.builder.resources.%s: unknown key %q (allowed: %s)", name, k, allowVram ? "cpu, ram, vram, scratchFreeSpace" : "cpu, ram, scratchFreeSpace")
615
659
  }
616
660
  ll.assert(!is_undefined(block.cpu) && !is_undefined(block.ram),
617
661
  "exec.builder.resources.%s: cpu and ram are required", name)
@@ -636,15 +680,30 @@ builder := func() {
636
680
  "exec.builder.resources: onGPU was set without onCPU (GPU required), but this backend has no GPU support (exec.hasGpu is false). Add an onCPU block for an adaptive CPU fallback, or run on a GPU-enabled backend.")
637
681
  }
638
682
 
683
+
684
+
685
+
686
+ setScratchFrom := func(block, ctx) {
687
+ if is_undefined(block.scratchFreeSpace) {
688
+ scratchFreeSpace = undefined
689
+ scratchFormulaAst = undefined
690
+ scratchFormulaFallback = undefined
691
+ return
692
+ }
693
+ setScratch(block.scratchFreeSpace, ctx)
694
+ }
695
+
639
696
  if useGPU {
640
697
  g := spec.onGPU
641
698
  setCpu(g.cpu, "resources.onGPU")
642
699
  setRam(g.ram, "resources.onGPU")
643
700
  setVram(g.vram, "resources.onGPU")
701
+ setScratchFrom(g, "resources.onGPU")
644
702
  } else {
645
703
  c := spec.onCPU
646
704
  setCpu(c.cpu, "resources.onCPU")
647
705
  setRam(c.ram, "resources.onCPU")
706
+ setScratchFrom(c, "resources.onCPU")
648
707
 
649
708
 
650
709
  gpuMemory = undefined
@@ -1333,10 +1392,12 @@ builder := func() {
1333
1392
 
1334
1393
 
1335
1394
 
1336
- hasFormula := !is_undefined(memFormulaAst) || !is_undefined(cpuFormulaAst) || !is_undefined(gpuFormulaAst)
1395
+ hasFormula := !is_undefined(memFormulaAst) || !is_undefined(cpuFormulaAst) ||
1396
+ !is_undefined(gpuFormulaAst) || !is_undefined(scratchFormulaAst)
1337
1397
  resolvedMem := undefined
1338
1398
  resolvedCpu := undefined
1339
1399
  resolvedGpu := undefined
1400
+ resolvedScratch := undefined
1340
1401
  lineCountMapResource := undefined
1341
1402
 
1342
1403
  if hasFormula {
@@ -1358,14 +1419,20 @@ builder := func() {
1358
1419
  fb := execFormula.applyFormulaFallback({
1359
1420
  ram: { ast: memFormulaAst, fallback: memFormulaFallback, static: ramRequest },
1360
1421
  cpu: { ast: cpuFormulaAst, fallback: cpuFormulaFallback, static: cpuRequest },
1361
- gpu: { ast: gpuFormulaAst, fallback: gpuFormulaFallback, static: gpuMemory }
1422
+ gpu: { ast: gpuFormulaAst, fallback: gpuFormulaFallback, static: gpuMemory },
1423
+ scratch: { ast: scratchFormulaAst, fallback: scratchFormulaFallback, static: scratchFreeSpace }
1362
1424
  })
1363
1425
  ll.assert(is_undefined(fb.err), fb.err)
1364
1426
  ramRequest = fb.ram
1365
1427
  cpuRequest = fb.cpu
1366
1428
  gpuMemory = fb.gpu
1429
+
1430
+
1431
+
1432
+ scratchFreeSpace = fb.scratch
1367
1433
  if is_int(ramRequest) { ramRequest = string(ramRequest) + "b" }
1368
1434
  if is_int(gpuMemory) { gpuMemory = string(gpuMemory) + "b" }
1435
+ if is_int(scratchFreeSpace) { scratchFreeSpace = string(scratchFreeSpace) + "b" }
1369
1436
  } else {
1370
1437
  tagMap := {}
1371
1438
  for fileName, tag in fileTags {
@@ -1390,6 +1457,11 @@ builder := func() {
1390
1457
  refs := execFormula.referencedMetricFiles(resolvedGpu)
1391
1458
  if !is_undefined(refs.lineCount) { sets.add(neededLineCount, refs.lineCount...) }
1392
1459
  }
1460
+ if !is_undefined(scratchFormulaAst) {
1461
+ resolvedScratch = execFormula.resolveAst(scratchFormulaAst, tagMap, allFiles)
1462
+ refs := execFormula.referencedMetricFiles(resolvedScratch)
1463
+ if !is_undefined(refs.lineCount) { sets.add(neededLineCount, refs.lineCount...) }
1464
+ }
1393
1465
 
1394
1466
  if len(neededLineCount) > 0 {
1395
1467
  perFile := {}
@@ -1419,6 +1491,9 @@ builder := func() {
1419
1491
 
1420
1492
  if !is_undefined(gpuMemory) { quotaData.gpuMemory = gpuMemory }
1421
1493
  }
1494
+
1495
+
1496
+ if !is_undefined(scratchFreeSpace) { quotaData.scratchFreeSpace = scratchFreeSpace }
1422
1497
  metaExecInputs := {
1423
1498
  quota: smart.createJsonResource(quotaData)
1424
1499
  }
@@ -1442,6 +1517,7 @@ builder := func() {
1442
1517
  if !is_undefined(resolvedMem) { metaExecInputs[execConstants.META_INPUT_MEM_FORMULA] = smart.createJsonResource(resolvedMem) }
1443
1518
  if !is_undefined(resolvedCpu) { metaExecInputs[execConstants.META_INPUT_CPU_FORMULA] = smart.createJsonResource(resolvedCpu) }
1444
1519
  if !is_undefined(resolvedGpu) { metaExecInputs[execConstants.META_INPUT_GPU_FORMULA] = smart.createJsonResource(resolvedGpu) }
1520
+ if !is_undefined(resolvedScratch) { metaExecInputs[execConstants.META_INPUT_SCRATCH_FORMULA] = smart.createJsonResource(resolvedScratch) }
1445
1521
  if !is_undefined(lineCountMapResource) { pureExecInputs[execConstants.REGULAR_INPUT_LINE_COUNT] = lineCountMapResource }
1446
1522
 
1447
1523
 
@@ -56,6 +56,7 @@ quotaBuilder := func() {
56
56
  cpu_request := undefined
57
57
  ram_request := undefined
58
58
  gpu_request := undefined
59
+ scratch_request := undefined
59
60
 
60
61
  self = ll.toStrict({
61
62
 
@@ -127,6 +128,30 @@ quotaBuilder := func() {
127
128
 
128
129
 
129
130
 
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+ scratchFreeSpace: func(amount) {
139
+ validation.assertType(
140
+ amount,
141
+ ["or", "number", "string", "null"],
142
+ "exec.quota.builder.scratchFreeSpace: scratch space amount should be a number or string")
143
+ ll.assert(is_undefined(amount) || is_string(amount) || amount > 0,
144
+ "exec.quota.builder.scratchFreeSpace: amount in bytes should be greater than 0")
145
+ scratch_request = amount
146
+
147
+ return self
148
+ },
149
+
150
+
151
+
152
+
153
+
154
+
130
155
  build: func() {
131
156
  ll.assert(queue_name != "", "exec.quota.builder: queue name is mandatory and could not be empty string")
132
157
 
@@ -142,6 +167,9 @@ quotaBuilder := func() {
142
167
  if !is_undefined(gpu_request) {
143
168
  data.gpuMemory = gpu_request
144
169
  }
170
+ if !is_undefined(scratch_request) {
171
+ data.scratchFreeSpace = scratch_request
172
+ }
145
173
 
146
174
  return smart.ephemeralBuilder(_RTYPE_QUOTA, json.encode(data)).lockAndBuild()
147
175
  }
@@ -82,5 +82,10 @@ export ll.toStrict({
82
82
 
83
83
 
84
84
 
85
+ hasScratchSpace: _isEnabled("scratchSpace"),
86
+
87
+
88
+
89
+
85
90
  multiStepProgress: _isEnabled("multiStepProgress")
86
91
  })
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/workflow-tengo",
3
- "version": "6.8.3",
3
+ "version": "6.9.0",
4
4
  "description": "Tengo SDK library",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -19,11 +19,11 @@
19
19
  "@milaboratories/pframes-rs-wasip2": "1.1.56",
20
20
  "@milaboratories/software-pframes-conv": "2.2.9",
21
21
  "@platforma-open/milaboratories.software-small-binaries": "^2.1.1",
22
- "@platforma-open/milaboratories.software-ptabler": "2.1.8",
23
- "@platforma-open/milaboratories.software-ptexter": "1.2.4"
22
+ "@platforma-open/milaboratories.software-ptexter": "1.2.4",
23
+ "@platforma-open/milaboratories.software-ptabler": "2.1.8"
24
24
  },
25
25
  "devDependencies": {
26
- "@platforma-sdk/tengo-builder": "4.0.23"
26
+ "@platforma-sdk/tengo-builder": "4.0.25"
27
27
  },
28
28
  "scripts": {
29
29
  "type-check": "pl-tengo check",