package main

import (
	"bufio"
	"encoding/csv"
	"encoding/gob"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strings"

	"gorgonia.org/gorgonia"
	"gorgonia.org/tensor"
)

type ParsedData struct {
	Input  string
	Output string
}

const maxTrainMessages = 1000 // Reduced to manage memory more efficiently

func LoadCSVFiles(dirname string) ([]ParsedData, error) {
	files, err := os.ReadDir(dirname)
	if err != nil {
		return nil, err
	}

	var data []ParsedData
	for _, file := range files {
		if strings.HasSuffix(file.Name(), ".csv") {
			f, err := os.Open(filepath.Join(dirname, file.Name()))
			if err != nil {
				return nil, err
			}
			defer f.Close()

			r := csv.NewReader(f)
			records, err := r.ReadAll()
			if err != nil {
				return nil, err
			}

			for i := 1; i < len(records); i++ {
				record := records[i]
				if len(record) >= 5 {
					data = append(data, ParsedData{
						Input:  record[4],
						Output: record[5],
					})
				}
			}
		}
	}
	return data, nil
}

func Tokenize(text string) []string {
	reg, err := regexp.Compile("[^a-zA-Z0-9]+")
	if err != nil {
		log.Fatalf("Regex compilation failed: %v", err)
	}
	cleanedText := reg.ReplaceAllString(text, " ")
	return strings.Fields(strings.ToLower(cleanedText))
}

func BuildVocab(data []ParsedData) map[string]int {
	vocab := make(map[string]int)
	for _, item := range data {
		tokens := append(Tokenize(item.Input), Tokenize(item.Output)...)
		for _, token := range tokens {
			if _, exists := vocab[token]; !exists {
				vocab[token] = len(vocab)
			}
		}
	}
	return vocab
}

func Vectorize(tokens []string, vocab map[string]int) []float32 {
	vector := make([]float32, len(vocab))
	for _, token := range tokens {
		if idx, exists := vocab[token]; exists {
			vector[idx] += 1
		}
	}
	return vector
}

func SaveWeights(weights *tensor.Dense, filename string) error {
	f, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer f.Close()

	encoder := gob.NewEncoder(f)
	return encoder.Encode(weights)
}

func LoadWeights(filename string) (*tensor.Dense, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	var weights tensor.Dense
	decoder := gob.NewDecoder(f)
	if err := decoder.Decode(&weights); err != nil {
		return nil, err
	}
	return &weights, nil
}

func SaveVocabulary(vocab map[string]int, filename string) error {
	f, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer f.Close()

	encoder := gob.NewEncoder(f)
	return encoder.Encode(vocab)
}

func LoadVocabulary(filename string) (map[string]int, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	var vocab map[string]int
	decoder := gob.NewDecoder(f)
	if err := decoder.Decode(&vocab); err != nil {
		return nil, err
	}
	return vocab, nil
}

func trainModel(trainDir string, maxTrainMessages int) {
	parsedData, err := LoadCSVFiles(trainDir)
	if err != nil {
		log.Fatalf("Error loading CSV files: %v", err)
	}

	if maxTrainMessages > len(parsedData) {
		maxTrainMessages = len(parsedData)
	}

	vocab := BuildVocab(parsedData)
	if err := SaveVocabulary(vocab, "vocab.gob"); err != nil {
		log.Fatalf("Error saving vocabulary: %v", err)
	}

	parsedData = parsedData[:maxTrainMessages]
	fmt.Printf("Loaded %d training records\n", len(parsedData))

	batchSize := 32 // Further reduced batch size to decrease memory usage
	totalSamples := len(parsedData)
	inputSize, outputSize := len(vocab), len(vocab)

	g := gorgonia.NewGraph()

	w := gorgonia.NewMatrix(g, tensor.Float32, gorgonia.WithShape(inputSize, outputSize), gorgonia.WithInit(gorgonia.GlorotN(1.0)))

	optimizer := gorgonia.NewAdamSolver(gorgonia.WithLearnRate(0.001))

	machine := gorgonia.NewTapeMachine(g, gorgonia.BindDualValues(w))
	defer machine.Close()

	for epoch := 0; epoch < 2; epoch++ { // Reduced epochs for faster iteration in limited memory environments
		for start := 0; start < totalSamples; start += batchSize {
			end := start + batchSize
			if end > totalSamples {
				end = totalSamples
			}

			xVal := tensor.New(tensor.WithShape(end-start, inputSize), tensor.Of(tensor.Float32))
			yVal := tensor.New(tensor.WithShape(end-start, outputSize), tensor.Of(tensor.Float32))

			for i := start; i < end; i++ {
				inputTokens := Tokenize(parsedData[i].Input)
				inputVec := Vectorize(inputTokens, vocab)
				outputTokens := Tokenize(parsedData[i].Output)
				outputVec := Vectorize(outputTokens, vocab)

				offset := (i - start) * inputSize
				copy(xVal.Data().([]float32)[offset:], inputVec)
				offsetY := (i - start) * outputSize
				copy(yVal.Data().([]float32)[offsetY:], outputVec)
			}

			x := gorgonia.NewMatrix(g, tensor.Float32, gorgonia.WithShape(end-start, inputSize), gorgonia.WithValue(xVal))
			y := gorgonia.NewMatrix(g, tensor.Float32, gorgonia.WithShape(end-start, outputSize), gorgonia.WithValue(yVal))

			yhat := gorgonia.Must(gorgonia.Mul(x, w))
			loss := gorgonia.Must(gorgonia.Mean(gorgonia.Must(gorgonia.Square(gorgonia.Must(gorgonia.Sub(yhat, y))))))

			if _, err := gorgonia.Grad(loss, w); err != nil {
				log.Fatalf("Failed to create computation graph: %v", err)
			}

			if err := machine.RunAll(); err != nil {
				log.Fatalf("Machine run error: %v", err)
			}

			optimizer.Step(gorgonia.NodesToValueGrads([]*gorgonia.Node{w}))

			machine.Reset()

			progress := float64(end) / float64(totalSamples) * 100
			fmt.Printf("Epoch %d: Processed batch from %d to %d (%.2f%% complete)\n", epoch+1, start, end, progress)
		}
	}

	fmt.Println("Model training complete")

	if err := SaveWeights(w.Value().(*tensor.Dense), "model_weights.gob"); err != nil {
		log.Fatalf("Error saving model weights: %v", err)
	} else {
		fmt.Println("Model weights saved successfully.")
	}
}

func interactWithModel() {
	weights, err := LoadWeights("model_weights.gob")
	if err != nil {
		log.Fatalf("Error loading model weights: %v", err)
	}

	vocab, err := LoadVocabulary("vocab.gob")
	if err != nil {
		log.Fatalf("Error loading vocabulary: %v", err)
	}

	reverseVocab := make(map[int]string)
	for word, idx := range vocab {
		reverseVocab[idx] = word
	}

	inputSize := len(vocab)
	reader := bufio.NewReader(os.Stdin)

	for {
		fmt.Print("Ask a question (or type 'exit' to quit): ")
		text, _ := reader.ReadString('\n')
		text = strings.TrimSpace(text)

		if text == "exit" {
			break
		}

		tokens := Tokenize(text)
		inputVec := Vectorize(tokens, vocab)

		xVal := tensor.New(tensor.WithShape(1, inputSize), tensor.Of(tensor.Float32))
		copy(xVal.Data().([]float32), inputVec)

		g := gorgonia.NewGraph()
		x := gorgonia.NewMatrix(g, tensor.Float32, gorgonia.WithShape(1, inputSize), gorgonia.WithValue(xVal))
		outputSize := len(vocab)
		w := gorgonia.NewMatrix(g, tensor.Float32, gorgonia.WithShape(inputSize, outputSize), gorgonia.WithValue(weights))

		yhat := gorgonia.Must(gorgonia.Mul(x, w))

		machine := gorgonia.NewTapeMachine(g)
		defer machine.Close()

		if err := machine.RunAll(); err != nil {
			log.Fatalf("Machine run error: %v", err)
		}

		predictionsVal := yhat.Value().Data().([]float32)
		topIndices := getTopIndices(predictionsVal, 5)

		var responseTokens []string
		for _, idx := range topIndices {
			if word, exists := reverseVocab[idx]; exists {
				responseTokens = append(responseTokens, word)
			}
		}

		response := strings.Join(responseTokens, " ")
		fmt.Printf("Generated Response: %s\n", response)
		machine.Reset()
	}
}

func validateModel(validationDir string) {
	weights, err := LoadWeights("model_weights.gob")
	if err != nil {
		log.Fatalf("Error loading model weights: %v", err)
	}

	vocab, err := LoadVocabulary("vocab.gob")
	if err != nil {
		log.Fatalf("Error loading vocabulary: %v", err)
	}

	validationData, err := LoadCSVFiles(validationDir)
	if err != nil {
		log.Fatalf("Error loading validation CSV files: %v", err)
	}

	correct := 0
	total := len(validationData)

	for _, item := range validationData {
		inputTokens := Tokenize(item.Input)
		inputVec := Vectorize(inputTokens, vocab)

		// Create and run graph
		inputSize := len(vocab)
		xVal := tensor.New(tensor.WithShape(1, inputSize), tensor.Of(tensor.Float32))
		copy(xVal.Data().([]float32), inputVec)

		g := gorgonia.NewGraph()
		x := gorgonia.NewMatrix(g, tensor.Float32, gorgonia.WithShape(1, inputSize), gorgonia.WithValue(xVal))
		outputSize := len(vocab)
		w := gorgonia.NewMatrix(g, tensor.Float32, gorgonia.WithShape(inputSize, outputSize), gorgonia.WithValue(weights))

		yhat := gorgonia.Must(gorgonia.Mul(x, w))

		machine := gorgonia.NewTapeMachine(g)
		defer machine.Close()

		if err := machine.RunAll(); err != nil {
			log.Fatalf("Machine run error: %v", err)
		}

		predictionsVal := yhat.Value().Data().([]float32)
		topIndex := getTopIndices(predictionsVal, 1)[0]

		// Check if the top prediction matches any output tokens
		outputTokens := Tokenize(item.Output)
		for _, token := range outputTokens {
			if idx, exists := vocab[token]; exists && idx == topIndex {
				correct++
				break
			}
		}

		machine.Reset()
	}

	accuracy := float64(correct) / float64(total) * 100
	fmt.Printf("Validation Accuracy: %.2f%%\n", accuracy)
}

func getTopIndices(values []float32, n int) []int {
	type kv struct {
		Key   int
		Value float32
	}

	var ss []kv
	for i, val := range values {
		ss = append(ss, kv{i, val})
	}

	sort.Slice(ss, func(i, j int) bool {
		return ss[i].Value > ss[j].Value
	})

	var indices []int
	for i := 0; i < n && i < len(ss); i++ {
		indices = append(indices, ss[i].Key)
	}
	return indices
}

func main() {
	fmt.Print("Enter mode of operation (t for training, v for validation, d for dialogue): ")
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	mode := scanner.Text()

	switch mode {
	case "t":
		trainModel("train", maxTrainMessages)
	case "v":
		validateModel("valid")
	case "d":
		interactWithModel()
	default:
		fmt.Println("Unknown mode. Use 't' for training, 'v' for validation, or 'd' for dialogue.")
	}
}


исправь ошибку

Enter mode of operation (t for training, v for validation, d for dialogue): t
Loaded 1000 training records
fatal error: runtime: cannot allocate memory

runtime stack:
runtime.throw({0xdfa3af?, 0xffffffffffffef30?})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/panic.go:1023 +0x65 fp=0xcabebff548 sp=0xcabebff518 pc=0x62d205
runtime.persistentalloc1(0x10d0, 0xcabebff5b0?, 0x13ba218)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/malloc.go:1576 +0x24d fp=0xcabebff598 sp=0xcabebff548 pc=0x602a0d
runtime.persistentalloc.func1()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/malloc.go:1529 +0x28 fp=0xcabebff5c8 sp=0xcabebff598 pc=0x6027a8
runtime.persistentalloc(0x7ffb54d03bf0?, 0x0?, 0x800000?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/malloc.go:1528 +0x5c fp=0xcabebff610 sp=0xcabebff5c8 pc=0x60271c
runtime.(*mheap).sysAlloc(0x1339320, 0x80c000dfe000?, 0x1349720, 0x1)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/malloc.go:776 +0x253 fp=0xcabebff6c8 sp=0xcabebff610 pc=0x601093
runtime.(*mheap).grow(0x1339320, 0x20157744b?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mheap.go:1484 +0x76 fp=0xcabebff748 sp=0xcabebff6c8 pc=0x61e7b6
runtime.(*mheap).allocSpan(0x1339320, 0x20157744b, 0x0, 0x1)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mheap.go:1246 +0x1b0 fp=0xcabebff7e8 sp=0xcabebff748 pc=0x61e050
runtime.(*mheap).alloc.func1()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mheap.go:964 +0x5c fp=0xcabebff830 sp=0xcabebff7e8 pc=0x61dadc
runtime.systemstack(0xc000604000)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:509 +0x49 fp=0xcabebff840 sp=0xcabebff830 pc=0x65d929

goroutine 1 gp=0xc000068000 m=9 mp=0xc000600008 [running]:
runtime.systemstack_switch()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:474 +0x8 fp=0xc000037778 sp=0xc000037768 pc=0x65d8c8
runtime.(*mheap).alloc(0x402aee896000?, 0x20157744b?, 0x5d?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mheap.go:958 +0x5b fp=0xc0000377c0 sp=0xc000037778 pc=0x61da3b
runtime.(*mcache).allocLarge(0x10?, 0x402aee895200, 0x1)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mcache.go:234 +0x87 fp=0xc000037810 sp=0xc0000377c0 pc=0x60ac27
runtime.mallocgc(0x402aee895200, 0xd39ee0, 0x1)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/malloc.go:1165 +0x597 fp=0xc000037898 sp=0xc000037810 pc=0x601f77
runtime.makeslice(0x18048eea5e66e470?, 0x6172fc?, 0x13b8040?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/slice.go:107 +0x49 fp=0xc0000378c0 sp=0xc000037898 pc=0x6432e9
gorgonia.org/gorgonia.GlorotEtAlN64(0xc0000379a0?, {0xc05d962670?, 0x293d2889958?, 0x20?})
        C:/Users/79685/go/pkg/mod/gorgonia.org/gorgonia@v0.9.18/weights.go:370 +0x131 fp=0xc000037918 sp=0xc0000378c0 pc=0xce4bd1
gorgonia.org/gorgonia.GlorotEtAlN32(0x0?, {0xc05d962670?, 0xc043dea060?, 0xc000037998?})
        C:/Users/79685/go/pkg/mod/gorgonia.org/gorgonia@v0.9.18/weights.go:381 +0x18 fp=0xc000037958 sp=0xc000037918 pc=0xce4c98
main.trainModel.GlorotN.func1({{0xebc7c0, 0xd39ea0}}, {0xc05d962670, 0x2, 0x2})
        C:/Users/79685/go/pkg/mod/gorgonia.org/gorgonia@v0.9.18/weights.go:215 +0xcc fp=0xc0000379c8 sp=0xc000037958 pc=0xd04f2c
main.trainModel.WithInit.func2(0xc000194000)
        C:/Users/79685/go/pkg/mod/gorgonia.org/gorgonia@v0.9.18/node.go:202 +0x8c fp=0xc000037a30 sp=0xc0000379c8 pc=0xd04dcc
gorgonia.org/gorgonia.newNode({0xc043dea020, 0x4, 0x4?})
        C:/Users/79685/go/pkg/mod/gorgonia.org/gorgonia@v0.9.18/node.go:279 +0xaa fp=0xc000037a68 sp=0xc000037a30 pc=0xc9ad4a
gorgonia.org/gorgonia.NewUniqueNode({0xc043dea020?, 0xc000037b00?, 0x10?})
        C:/Users/79685/go/pkg/mod/gorgonia.org/gorgonia@v0.9.18/node.go:289 +0x18 fp=0xc000037aa0 sp=0xc000037a68 pc=0xc9add8
gorgonia.org/gorgonia.NewMatrix(0xc043e62000, {{0xebc7c0, 0xd39ea0}}, {0xc000037e20, 0x2, 0x1?})
        C:/Users/79685/go/pkg/mod/gorgonia.org/gorgonia@v0.9.18/gorgonia.go:69 +0x1b2 fp=0xc000037b28 sp=0xc000037aa0 pc=0xc91572
main.trainModel({0xdebde5?, 0xc000072028?}, 0x3e8)
        D:/JBProjects/GOLAND/Learn/main.go:169 +0x2d6 fp=0xc000037e58 sp=0xc000037b28 pc=0xd033b6
main.main()
        D:/JBProjects/GOLAND/Learn/main.go:385 +0x11e fp=0xc000037f50 sp=0xc000037e58 pc=0xd06f5e
runtime.main()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:271 +0x28b fp=0xc000037fe0 sp=0xc000037f50 pc=0x62fb2b
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000037fe8 sp=0xc000037fe0 pc=0x65f8e1

goroutine 2 gp=0xc000068700 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00006bfa8 sp=0xc00006bf88 pc=0x62ff2e
runtime.goparkunlock(...)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:408
runtime.forcegchelper()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:326 +0xb8 fp=0xc00006bfe0 sp=0xc00006bfa8 pc=0x62fdb8
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00006bfe8 sp=0xc00006bfe0 pc=0x65f8e1
created by runtime.init.6 in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:314 +0x1a

goroutine 3 gp=0xc000068a80 m=nil [GC sweep wait]:
runtime.gopark(0x1?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00006df80 sp=0xc00006df60 pc=0x62ff2e
runtime.goparkunlock(...)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:408
runtime.bgsweep(0xc0000281c0)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgcsweep.go:318 +0xdf fp=0xc00006dfc8 sp=0xc00006df80 pc=0x61a47f
runtime.gcenable.gowrap1()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:203 +0x25 fp=0xc00006dfe0 sp=0xc00006dfc8 pc=0x60ed45
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00006dfe8 sp=0xc00006dfe0 pc=0x65f8e1
created by runtime.gcenable in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:203 +0x66

goroutine 4 gp=0xc000068c40 m=nil [GC scavenge wait]:
runtime.gopark(0x5fc6c0?, 0x7b1ff?, 0x0?, 0x0?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00007df78 sp=0xc00007df58 pc=0x62ff2e
runtime.goparkunlock(...)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:408
runtime.(*scavengerState).park(0x1319fe0)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc00007dfa8 sp=0xc00007df78 pc=0x617e29
runtime.bgscavenge(0xc0000281c0)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgcscavenge.go:658 +0x59 fp=0xc00007dfc8 sp=0xc00007dfa8 pc=0x6183d9
runtime.gcenable.gowrap2()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:204 +0x25 fp=0xc00007dfe0 sp=0xc00007dfc8 pc=0x60ece5
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007dfe8 sp=0xc00007dfe0 pc=0x65f8e1
created by runtime.gcenable in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:204 +0xa5

goroutine 5 gp=0xc000068fc0 m=nil [finalizer wait]:
runtime.gopark(0x2938b65ad88?, 0xc000032030?, 0x0?, 0x0?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00006fe20 sp=0xc00006fe00 pc=0x62ff2e
runtime.runfinq()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mfinal.go:194 +0x107 fp=0xc00006ffe0 sp=0xc00006fe20 pc=0x60ddc7
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00006ffe8 sp=0xc00006ffe0 pc=0x65f8e1
created by runtime.createfing in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mfinal.go:164 +0x3d

goroutine 18 gp=0xc0001041c0 m=nil [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000079f50 sp=0xc000079f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000079fe0 sp=0xc000079f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000079fe8 sp=0xc000079fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 34 gp=0xc000480000 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7654d8fec?, 0x3?, 0xd4?, 0x25?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000487f50 sp=0xc000487f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000487fe0 sp=0xc000487f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000487fe8 sp=0xc000487fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 19 gp=0xc000104380 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7658acc18?, 0x1?, 0x30?, 0x89?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00007bf50 sp=0xc00007bf30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc00007bfe0 sp=0xc00007bf50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00007bfe8 sp=0xc00007bfe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 35 gp=0xc0004801c0 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7656c4ea0?, 0x3?, 0xcc?, 0x31?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000489f50 sp=0xc000489f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000489fe0 sp=0xc000489f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000489fe8 sp=0xc000489fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 20 gp=0xc000104540 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7656c4ea0?, 0x1?, 0x10?, 0x4d?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000483f50 sp=0xc000483f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000483fe0 sp=0xc000483f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000483fe8 sp=0xc000483fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 36 gp=0xc000480380 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7659bdae4?, 0x3?, 0x0?, 0x0?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00048ff50 sp=0xc00048ff30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc00048ffe0 sp=0xc00048ff50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00048ffe8 sp=0xc00048ffe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 21 gp=0xc000104700 m=nil [GC worker (idle)]:
runtime.gopark(0x13b8040?, 0x1?, 0xcc?, 0xe?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000485f50 sp=0xc000485f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000485fe0 sp=0xc000485f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000485fe8 sp=0xc000485fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 37 gp=0xc000480540 m=nil [GC worker (idle)]:
runtime.gopark(0x13b8040?, 0x1?, 0x48?, 0xfc?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000491f50 sp=0xc000491f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000491fe0 sp=0xc000491f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000491fe8 sp=0xc000491fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 22 gp=0xc0001048c0 m=nil [GC worker (idle)]:
runtime.gopark(0x13b8040?, 0x1?, 0x1c?, 0xcb?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00048bf50 sp=0xc00048bf30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc00048bfe0 sp=0xc00048bf50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00048bfe8 sp=0xc00048bfe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 38 gp=0xc000480700 m=nil [GC worker (idle)]:
runtime.gopark(0x13b8040?, 0x1?, 0x0?, 0x0?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000497f50 sp=0xc000497f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000497fe0 sp=0xc000497f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000497fe8 sp=0xc000497fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 23 gp=0xc000104a80 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7657b8848?, 0x3?, 0x8?, 0x9d?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00048df50 sp=0xc00048df30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc00048dfe0 sp=0xc00048df50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00048dfe8 sp=0xc00048dfe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 39 gp=0xc0004808c0 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7659bdae4?, 0x3?, 0xe0?, 0x56?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000499f50 sp=0xc000499f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000499fe0 sp=0xc000499f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000499fe8 sp=0xc000499fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 24 gp=0xc000104c40 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7659bdae4?, 0x3?, 0x7c?, 0xed?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000493f50 sp=0xc000493f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000493fe0 sp=0xc000493f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000493fe8 sp=0xc000493fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 40 gp=0xc000480a80 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7658acc18?, 0x3?, 0xe0?, 0x56?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc00049ff50 sp=0xc00049ff30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc00049ffe0 sp=0xc00049ff50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00049ffe8 sp=0xc00049ffe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 25 gp=0xc000104e00 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7659bdae4?, 0x1?, 0x30?, 0x36?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc000495f50 sp=0xc000495f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc000495fe0 sp=0xc000495f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000495fe8 sp=0xc000495fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

goroutine 41 gp=0xc000480c40 m=nil [GC worker (idle)]:
runtime.gopark(0x3d7659bdae4?, 0x3?, 0x84?, 0x8a?, 0x0?)
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/proc.go:402 +0xce fp=0xc0004a1f50 sp=0xc0004a1f30 pc=0x62ff2e
runtime.gcBgMarkWorker()
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1310 +0xe5 fp=0xc0004a1fe0 sp=0xc0004a1f50 pc=0x610e85
runtime.goexit({})
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0004a1fe8 sp=0xc0004a1fe0 pc=0x65f8e1
created by runtime.gcBgMarkStartWorkers in goroutine 1
        C:/Users/79685/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.windows-amd64/src/runtime/mgc.go:1234 +0x1c

Process finished with the exit code 2