diff --git a/pixie.nimble b/pixie.nimble index 2e01f52..13f93a5 100644 --- a/pixie.nimble +++ b/pixie.nimble @@ -10,7 +10,7 @@ requires "vmath >= 1.1.4" requires "chroma >= 0.2.6" requires "zippy >= 0.10.3" requires "flatty >= 0.3.4" -requires "nimsimd >= 1.1.10" +requires "nimsimd >= 1.2.0" requires "bumpy >= 1.1.1" task bindings, "Generate bindings": diff --git a/src/pixie/simd.nim b/src/pixie/simd.nim index 57b0b8d..bc2cbb6 100644 --- a/src/pixie/simd.nim +++ b/src/pixie/simd.nim @@ -1,16 +1,18 @@ -import simd/internal +import nimsimd/hassimd -export internal +export hassimd const allowSimd* = not defined(pixieNoSimd) and not defined(tcc) when allowSimd: when defined(amd64): - import simd/sse2, simd/avx, simd/avx2 - export sse2, avx, avx2 + import simd/sse2 + export sse2 when not defined(pixieNoAvx): - import nimsimd/runtimecheck + import nimsimd/runtimecheck, simd/avx, simd/avx2 + export avx, avx2 + let cpuHasAvx* = checkInstructionSets({AVX}) cpuHasAvx2* = checkInstructionSets({AVX, AVX2}) diff --git a/src/pixie/simd/avx.nim b/src/pixie/simd/avx.nim index 82b4333..dfcd9cf 100644 --- a/src/pixie/simd/avx.nim +++ b/src/pixie/simd/avx.nim @@ -1,4 +1,4 @@ -import chroma, internal, nimsimd/avx +import chroma, nimsimd/hassimd, nimsimd/avx when defined(gcc) or defined(clang): {.localPassc: "-mavx".} diff --git a/src/pixie/simd/avx2.nim b/src/pixie/simd/avx2.nim index 06c41f2..9a02657 100644 --- a/src/pixie/simd/avx2.nim +++ b/src/pixie/simd/avx2.nim @@ -1,4 +1,4 @@ -import avx, chroma, internal, nimsimd/avx2, pixie/blends, pixie/common, vmath +import avx, chroma, nimsimd/hassimd, nimsimd/avx2, pixie/blends, pixie/common, vmath when defined(gcc) or defined(clang): {.localPassc: "-mavx2".} diff --git a/src/pixie/simd/internal.nim b/src/pixie/simd/internal.nim deleted file mode 100644 index 9516890..0000000 --- a/src/pixie/simd/internal.nim +++ /dev/null @@ -1,123 +0,0 @@ -import std/macros, std/tables - -var simdProcs* {.compiletime.}: Table[string, NimNode] - -proc procName(procedure: NimNode): string = - ## Given a procedure this returns the name as a string. - let nameNode = procedure[0] - if nameNode.kind == nnkPostfix: - nameNode[1].strVal - else: - nameNode.strVal - -proc procArguments(procedure: NimNode): seq[NimNode] = - ## Given a procedure this gets the arguments as a list. - for i, arg in procedure[3]: - if i > 0: - for j in 0 ..< arg.len - 2: - result.add(arg[j]) - -proc procReturnType(procedure: NimNode): NimNode = - ## Given a procedure this gets the return type. - procedure[3][0] - -proc procSignature(procedure: NimNode): string = - ## Given a procedure this returns the signature as a string. - result = "(" - - for i, arg in procedure[3]: - if i > 0: - for j in 0 ..< arg.len - 2: - result &= arg[^2].repr & ", " - - if procedure[3].len > 1: - result = result[0 ..^ 3] - - result &= ")" - - let ret = procedure.procReturnType() - if ret.kind != nnkEmpty: - result &= ": " & ret.repr - -proc callAndReturn(name: NimNode, procedure: NimNode): NimNode = - ## Produces a procedure call with arguments. - let - retType = procedure.procReturnType() - call = newNimNode(nnkCall) - call.add(name) - for arg in procedure.procArguments(): - call.add(arg) - if retType.kind == nnkEmpty: - result = quote do: - `call` - return - else: - result = quote do: - return `call` - -macro simd*(procedure: untyped) = - let signature = procedure.procName() & procSignature(procedure) - simdProcs[signature] = procedure.copy() - return procedure - -macro hasSimd*(procedure: untyped) = - let - name = procedure.procName() - nameNeon = name & "Neon" - nameSse2 = name & "Sse2" - nameAvx = name & "Avx" - nameAvx2 = name & "Avx2" - callNeon = callAndReturn(ident(nameNeon), procedure) - callSse2 = callAndReturn(ident(nameSse2), procedure) - callAvx = callAndReturn(ident(nameAvx), procedure) - callAvx2 = callAndReturn(ident(nameAvx2), procedure) - - var - foundSimd: bool - - if procedure[6].kind != nnkStmtList: - error("hasSimd proc body must start with nnkStmtList") - - var insertIdx = 0 - if procedure[6][0].kind == nnkCommentStmt: - insertIdx = 1 - - when defined(amd64) and not defined(pixieNoAvx): - if nameAvx2 & procSignature(procedure) in simdProcs: - foundSimd = true - procedure[6].insert(insertIdx, quote do: - if cpuHasAvx2: - `callAvx2` - ) - inc insertIdx - if nameAvx & procSignature(procedure) in simdProcs: - foundSimd = true - procedure[6].insert(insertIdx, quote do: - if cpuHasAvx: - `callAvx` - ) - inc insertIdx - when defined(amd64): - if nameSse2 & procSignature(procedure) in simdProcs: - foundSimd = true - procedure[6].insert(insertIdx, quote do: - `callSse2` - ) - inc insertIdx - while procedure[6].len > insertIdx: - procedure[6].del(insertIdx) - elif defined(arm64): - if nameNeon & procSignature(procedure) in simdProcs: - foundSimd = true - procedure[6].insert(insertIdx, quote do: - `callNeon` - ) - inc insertIdx - while procedure[6].len > insertIdx: - procedure[6].del(insertIdx) - - when not defined(pixieNoSimd): - if not foundSimd: - echo "No SIMD found for " & name & procSignature(procedure) - - return procedure diff --git a/src/pixie/simd/neon.nim b/src/pixie/simd/neon.nim index 5159f7e..a9827db 100644 --- a/src/pixie/simd/neon.nim +++ b/src/pixie/simd/neon.nim @@ -1,4 +1,4 @@ -import chroma, internal, nimsimd/neon, pixie/blends, pixie/common, vmath +import chroma, nimsimd/hassimd, nimsimd/neon, pixie/blends, pixie/common, vmath when defined(release): {.push checks: off.} diff --git a/src/pixie/simd/sse2.nim b/src/pixie/simd/sse2.nim index 4d1110c..cd2057e 100644 --- a/src/pixie/simd/sse2.nim +++ b/src/pixie/simd/sse2.nim @@ -1,4 +1,4 @@ -import chroma, internal, nimsimd/sse2, pixie/blends, pixie/common, vmath +import chroma, nimsimd/hassimd, nimsimd/sse2, pixie/blends, pixie/common, vmath when defined(release): {.push checks: off.}