chore: auto-commit (95 archivos)
- cmd/fn/doctor.go - cmd/fn/main.go - cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt - cpp/apps/primitives_gallery/playground/tables/data_table.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.h - cpp/apps/primitives_gallery/playground/tables/self_test.cpp - cpp/apps/primitives_gallery/playground/tables/tql.cpp - cpp/apps/primitives_gallery/playground/tables/viz.cpp - cpp/apps/primitives_gallery/playground/tables/viz.h - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package ml
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// SdcliProgress contiene el estado de progreso parseado de una linea de stderr de sd-cli.
|
||||
type SdcliProgress struct {
|
||||
Step int `json:"step"`
|
||||
TotalSteps int `json:"total_steps"`
|
||||
ItPerSec float64 `json:"it_per_sec"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
// reProgress1 parsea el formato compacto: " 3/30 | 0.84it/s | 10%"
|
||||
var reProgress1 = regexp.MustCompile(`\s*(\d+)\s*/\s*(\d+)\s*\|[^|]*?([\d.]+)\s*it/s[^|]*?\|\s*([\d.]+)\s*%`)
|
||||
|
||||
// reProgress2 parsea el formato verbose: "sampling: step 3 of 30 (0.84 it/s)"
|
||||
var reProgress2 = regexp.MustCompile(`step\s+(\d+)\s+of\s+(\d+)\s*\(\s*([\d.]+)\s*it/s\)`)
|
||||
|
||||
// reProgress3 parsea el formato minimal: "step 3/30" o "progress: 3/30"
|
||||
var reProgress3 = regexp.MustCompile(`(?:progress[:\s]+)?(\d+)\s*/\s*(\d+)`)
|
||||
|
||||
// SdcliParseProgress parsea una linea de stderr de stable-diffusion.cpp / sd-cli
|
||||
// y extrae el estado de progreso. Retorna (SdcliProgress, true) si la linea
|
||||
// contiene informacion de progreso reconocible; (zero, false) en caso contrario.
|
||||
// Funcion pura: sin I/O, sin estado mutable, determinista.
|
||||
func SdcliParseProgress(line string) (SdcliProgress, bool) {
|
||||
// Formato 1: " 3/30 | 0.84it/s | 10%"
|
||||
if m := reProgress1.FindStringSubmatch(line); m != nil {
|
||||
step, err1 := strconv.Atoi(m[1])
|
||||
total, err2 := strconv.Atoi(m[2])
|
||||
itPerSec, err3 := strconv.ParseFloat(m[3], 64)
|
||||
pct, err4 := strconv.ParseFloat(m[4], 64)
|
||||
if err1 == nil && err2 == nil && err3 == nil && err4 == nil {
|
||||
return SdcliProgress{
|
||||
Step: step,
|
||||
TotalSteps: total,
|
||||
ItPerSec: itPerSec,
|
||||
Percent: pct,
|
||||
}, true
|
||||
}
|
||||
}
|
||||
|
||||
// Formato 2: "sampling: step 3 of 30 (0.84 it/s)"
|
||||
if m := reProgress2.FindStringSubmatch(line); m != nil {
|
||||
step, err1 := strconv.Atoi(m[1])
|
||||
total, err2 := strconv.Atoi(m[2])
|
||||
itPerSec, err3 := strconv.ParseFloat(m[3], 64)
|
||||
if err1 == nil && err2 == nil && err3 == nil && total > 0 {
|
||||
pct := 100.0 * float64(step) / float64(total)
|
||||
return SdcliProgress{
|
||||
Step: step,
|
||||
TotalSteps: total,
|
||||
ItPerSec: itPerSec,
|
||||
Percent: pct,
|
||||
}, true
|
||||
}
|
||||
}
|
||||
|
||||
// Formato 3: "step 3/30" o "progress: 3/30" sin velocidad
|
||||
if m := reProgress3.FindStringSubmatch(line); m != nil {
|
||||
step, err1 := strconv.Atoi(m[1])
|
||||
total, err2 := strconv.Atoi(m[2])
|
||||
if err1 == nil && err2 == nil && total > 0 {
|
||||
pct := 100.0 * float64(step) / float64(total)
|
||||
return SdcliProgress{
|
||||
Step: step,
|
||||
TotalSteps: total,
|
||||
ItPerSec: 0,
|
||||
Percent: pct,
|
||||
}, true
|
||||
}
|
||||
}
|
||||
|
||||
return SdcliProgress{}, false
|
||||
}
|
||||
Reference in New Issue
Block a user