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)
    

Reply via email to