Skip to content

Instantly share code, notes, and snippets.

@mattt
Last active January 27, 2019 20:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mattt/d725a54f9b5aa6a3eaa425f4e1f18f78 to your computer and use it in GitHub Desktop.
Save mattt/d725a54f9b5aa6a3eaa425f4e1f18f78 to your computer and use it in GitHub Desktop.
Sieve of Eratosthenes with Accelerate
// Calculate prime numbers in a given range
// using Sieve of Eratosthenes
import Accelerate
var primes: [Int] = []
let range = 0...999
var numbers = range.map(Float.init)
for n in range.dropLast() {
guard numbers[n] > 1 else { continue }
defer { primes.append(n) }
// Clear vector elements with given stride
// (i.e. set value to 0)
vDSP_vclr(&numbers,
numericCast(n),
numericCast(numbers.count / n))
}
print(primes)
@willie
Copy link

willie commented Oct 15, 2018

This is weird.

Put:

	let cnt = (numbers.count) / n
	print(numbers.count, n, cnt)
	numbers[0] = 1.0
	print(numbers)
	vDSP_vclr(&numbers,
			  numericCast(n),
			  numericCast(cnt))
	print(numbers)

results in this for n=3

11 3 3
[1.0, 1.0, 0.0, 3.0, 0.0, 5.0, 0.0, 7.0, 0.0, 9.0, 10.0]
[0.0, 1.0, 0.0, 0.0, 0.0, 5.0, 0.0, 7.0, 0.0, 9.0, 10.0]

It looks like vDSP_vclr clears numbers[0] regardless of stride and elements?

@mattt
Copy link
Author

mattt commented Oct 15, 2018

My understanding of the stride parameter is that a value of 2 , means "clear every 2nd (even) element", 3 means "clear every 3rd element)", etc. So yes, it clears numbers[0] each time, but that's fine because numbers < 2 aren't considered.

To clarify my point from before, I wonder if always rounding up numbers.count / n (like with ceil) would solve the problem. Adding 1 as you described would have the same effect (at least for any divisions that are rounded down.

@willie
Copy link

willie commented Oct 15, 2018

Here is what I figured out:

  1. numbers.count is the last number in the range + 1, so the number of elements calculation should be: (numbers.count - 1) / n
  2. there is no need to dropLast
  3. to account for the zeroth element behavior, it's easy enough to start vDSP_vclr at &numbers[n].

I'll post a modified version in a few.

@willie
Copy link

willie commented Oct 15, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment