# Parallelism

> NumKong for Go

`WorkerPool` provides pre-pinned goroutines with pre-configured SIMD state.
Create once, reuse across batch calls, close when done.
The pool amortizes `Device.ConfigureThread` + `LockOSThread` cost across all batch operations.

```go
package main

import (
	"fmt"

	nk "github.com/ashvardanian/NumKong/golang"
)

func main() {
	columns, depth, totalQueries := 1024, 128, 10000

	db := make([]float32, columns*depth)
	queries := make([]float32, totalQueries*depth)
	for i := range db { db[i] = float32(i%7) * 0.1 }
	for i := range queries { queries[i] = float32(i%11) * 0.1 }

	dbPacked := nk.NewDotsPackedMatrixF32(db, columns, depth)

	// Create a reusable pool (defaults to GOMAXPROCS workers)
	pool := nk.NewWorkerPool(8)
	defer pool.Close()

	// Packed batch operations dispatch to the pool
	results := make([]float64, totalQueries*columns)
	dbPacked.DotsF32WithPool(queries, results, totalQueries, pool)

	// Angular and Euclidean distances use the same pool
	angResults := make([]float64, totalQueries*columns)
	dbPacked.AngularsF32WithPool(queries, angResults, totalQueries, pool)

	fmt.Println("first result row:", results[:columns])
}
```

Symmetric operations also support pool-based parallelism:

```go
n, depth := 1000, 128
vectors := make([]float32, n*depth)
gram := make([]float64, n*n)

pool := nk.NewWorkerPool(0) // 0 = GOMAXPROCS
defer pool.Close()

nk.DotsSymmetricF32WithPool(vectors, n, depth, gram, pool)
```

For one-off parallel work without a pool, you can still use `ConfigureThread` directly:

```go
go func() {
	enabled, _ := nk.CPU().CapabilitiesEnabled()
	unlock, _ := nk.CPU().ConfigureThread(enabled) // lock thread + configure SIMD
	defer unlock()                                 // release the OS thread on return
	nk.DotsPackedF32(queries, dbPacked, results, rows)
}()
```

`import "github.com/ashvardanian/NumKong"`

## WorkerPool

WorkerPool runs batch kernels on goroutines pinned to OS threads, each configuring its SIMD state once.

```go
type WorkerPool struct {
    // contains filtered or unexported fields
}
```

Create it with [NewWorkerPool](#NewWorkerPool), reuse it across calls, and release it with [WorkerPool.Close](#Close).

## NewWorkerPool

NewWorkerPool starts n pinned workers, or GOMAXPROCS workers when n is not positive.

```go
func NewWorkerPool(n int) *WorkerPool
```

## Close

Close stops every worker and waits for it to exit.

```go
func (p *WorkerPool) Close()
```

## Size

Size returns the number of workers in the pool.

```go
func (p *WorkerPool) Size() int
```

