I'm working on a macro idea to allow a SIMD library where you can write simd
code once, and at _runtime_ the correct simd functions will be used based on
feature detection of the cpu.
I have a simple proof of concept here, this works, but I am unsure if this is
the best way to accomplish this:
**avx.nim**
proc add*(a:int,b:int) : int =
echo "avx add"
a+b
**sse.nim**
proc add*(a:int,b:int) : int =
echo "sse add"
a+b
**main.nim**
import avx
import sse
import macros
import rdstdin
# recursively process the AST replacing any simd. idents
proc replaceSIMD(node:NimNode, simdType:string) =
for node in node.children:
echo $node.kind
if node.kind == nnkIdent:
echo $node.ident
if node.ident == !"simd":
node.ident = !simdType
replaceSIMD(node,simdType)
macro SIMD_AVX(body:untyped): untyped =
replaceSIMD(body,"avx")
body
macro SIMD_SSE(body:untyped): untyped =
replaceSIMD(body,"sse")
body
# I think macros cannot do anything at runtime so we start with a template
template SIMD(body:untyped) =
let str = readLineFromStdin "sse or avx? "
# instead of calling different macros, is there a way to pass the
string?
# I tried this and got odd compile errors
if str == "sse":
SIMD_SSE(body)
if str == "avx":
SIMD_AVX(body)
# inside the SIMD statement, replace each instance of simd. with
# the appropriate SIMD type (avx, sse, etc)
SIMD:
echo $simd.add(1,2)