Thank you for your interest in contributing to the SIMD library! This document provides guidelines and information for contributors.
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/simd.git - Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes
- Run tests:
go test ./... - Run linter:
golangci-lint run - Commit your changes with a descriptive message
- Push to your fork and submit a pull request
- Go 1.25 or later
- GCC (for C reference implementation tests)
- golangci-lint (for linting)
# Run all tests
go test ./...
# Run tests with verbose output
go test -v ./...
# Run benchmarks
go test ./f64 -bench=. -benchmem
go test ./f32 -bench=. -benchmem
# Run linter
golangci-lint run
# Generate test expectations from C reference
cd testdata
gcc -O2 -march=native -o generate_expectations generate_expectations.c -lm
./generate_expectationssimd/
├── cpu/ # CPU feature detection
│ ├── cpu.go # Common types and functions
│ ├── cpu_amd64.go
│ ├── cpu_arm64.go
│ └── cpu_other.go
├── f64/ # float64 operations
│ ├── f64.go # Public API
│ ├── f64_go.go # Pure Go implementations
│ ├── f64_amd64.go # AMD64 dispatchers
│ ├── f64_amd64.s # AMD64 assembly
│ ├── f64_arm64.go # ARM64 dispatchers
│ ├── f64_arm64.s # ARM64 assembly
│ ├── f64_other.go # Fallback dispatchers
│ └── *_test.go # Tests and benchmarks
├── f32/ # float32 operations (same structure)
├── c128/ # complex128 operations (same structure)
├── testdata/ # C reference implementation
├── .githooks/ # Git pre-commit hooks
├── Taskfile.yml # Task runner configuration
├── doc.go # Package documentation
├── README.md
├── CONTRIBUTING.md
├── LICENSE
└── go.mod
When adding a new SIMD operation, follow these steps:
// OperationName performs [description].
// Processes min(len(dst), len(a)) elements.
func OperationName(dst, a []float64) {
n := min(len(dst), len(a))
if n == 0 {
return
}
operationName64(dst[:n], a[:n])
}func operationNameGo(dst, a []float64) {
for i := range dst {
dst[i] = // operation
}
}For AMD64 (f64_amd64.go):
func operationName64(dst, a []float64) {
if hasAVX && len(dst) >= 4 {
operationNameAVX(dst, a)
return
}
operationNameGo(dst, a)
}
//go:noescape
func operationNameAVX(dst, a []float64)For ARM64 (f64_arm64.go):
func operationName64(dst, a []float64) {
if hasNEON && len(dst) >= 2 {
operationNameNEON(dst, a)
return
}
operationNameGo(dst, a)
}
//go:noescape
func operationNameNEON(dst, a []float64)For other architectures (f64_other.go):
func operationName64(dst, a []float64) { operationNameGo(dst, a) }Add to f64_amd64.s and f64_arm64.s. For initial development, you can add a stub:
TEXT ·operationNameAVX(SB), $0-48
JMP ·operationNameGo(SB)Add tests in f64_test.go or create a new test file:
func TestOperationName(t *testing.T) {
tests := []struct {
name string
a []float64
want []float64
}{
{"empty", nil, nil},
{"single", []float64{1}, []float64{1}},
// Add more test cases
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dst := make([]float64, len(tt.a))
OperationName(dst, tt.a)
// Assert results
})
}
}Add the operation to testdata/generate_expectations.c for validation.
Update README.md to include the new operation in the API table.
- Follow standard Go formatting (
gofmt) - Use meaningful variable names
- Add doc comments for all public functions
- Keep functions focused and small
- Avoid magic numbers - use named constants
- Use Go's plan9 assembly syntax
- Include comments explaining the algorithm
- Handle remainder elements after SIMD loops
- Use
VZEROUPPERat the end of AVX functions (AMD64) - Test with various slice sizes to exercise all code paths
- Title: Use a clear, descriptive title
- Description: Explain what the PR does and why
- Tests: Include tests for new functionality
- Benchmarks: Include benchmarks for performance-critical code
- Documentation: Update README if adding new features
When reporting issues, please include:
- Go version (
go version) - Operating system and architecture
- Steps to reproduce
- Expected vs actual behavior
- Relevant code snippets
Feel free to open an issue for questions or discussions about potential contributions.