Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SIMD for dot product calculation on supported CPUs #48

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

philippgille
Copy link
Owner

@philippgille philippgille commented Mar 16, 2024

⚠️ WIP: I'd like to get rid of the golang.org/x/sys/cpu dependency

Using generated Assembler code from https://github.com/viterin/vek. That code is MIT licensed, which means we can use and copy it as long as we adhere to its terms, like preserving a copy of the license and copyright in the licensed material. chromem-go stays AGPL licensed.

Shoutout to @viterin 🙇‍♂️

@rinor
Copy link
Contributor

rinor commented May 13, 2024

can you rebase this branch please, just would like to test/push the changes from 4341c0e

@philippgille
Copy link
Owner Author

philippgille commented May 17, 2024

can you rebase this branch please, just would like to test/push the changes from 4341c0e

Oh nice!

Rebased ✔️

@rinor
Copy link
Contributor

rinor commented May 17, 2024

thanks #75 is ready for review

@rinor
Copy link
Contributor

rinor commented May 18, 2024

also do you think it's worth trying some non-simd stuff from https://sourcegraph.com/blog/slow-to-simd

Basically dotProduct function might look smth like:

// dotProduct calculates the dot product between two vectors.
// It's the same as cosine similarity for normalized vectors.
// The resulting value represents the similarity, so a higher value means the
// vectors are more similar.
func dotProduct(a, b []float32) (float32, error) {
	// The vectors must have the same length
	if len(a) != len(b) {
		return 0, errors.New("vectors must have the same length")
	}

	dotProduct := float32(0)
	vLen := len(a)

	switch {
	case simd.UseAVX2:
		dotProduct = simd.Dot_AVX2_F32(a, b)
	case vLen%4 == 0:
		for i := 0; i < vLen; i += 4 {
			aTmp := a[i : i+4 : i+4]
			bTmp := b[i : i+4 : i+4]
			s0 := aTmp[0] * bTmp[0]
			s1 := aTmp[1] * bTmp[1]
			s2 := aTmp[2] * bTmp[2]
			s3 := aTmp[3] * bTmp[3]
			dotProduct += s0 + s1 + s2 + s3
		}
	default:
		for i := range a {
			dotProduct += a[i] * b[i]
		}
	}

	return dotProduct, nil
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants