123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- discard """
- disabled: "arm64"
- cmd: "nim c --gc:arc $file"
- output: "y"
- """
- {.passC: "-march=native".}
- proc isAlignedCheck(p: pointer, alignment: int) =
- doAssert (cast[uint](p) and uint(alignment - 1)) == 0
- proc isAlignedCheck[T](p: ref T, alignment: int) =
- isAlignedCheck(cast[pointer](p), alignment)
- type
- m256d {.importc: "__m256d", header: "immintrin.h".} = object
- proc set1(x: float): m256d {.importc: "_mm256_set1_pd", header: "immintrin.h".}
- func `+`(a,b: m256d): m256d {.importc: "_mm256_add_pd", header: "immintrin.h".}
- proc `$`(a: m256d): string =
- result = $(cast[ptr float](a.addr)[])
- var res: seq[seq[m256d]]
- for _ in 1..1000:
- var x = newSeq[m256d](1)
- x[0] = set1(1.0) # test if operation causes segfault
- isAlignedCheck(x[0].addr, alignof(m256d))
- res.add x
- var res2: seq[m256d]
- for i in 1..10000:
- res2.setLen(res2.len + 1) # check if realloc works
- isAlignedCheck(res2[0].addr, alignof(m256d))
- proc lambdaGen(a, b: float, z: ref m256d) : auto =
- var x1 = new(m256d)
- var x2 = new(m256d)
- isAlignedCheck(x1, alignof(m256d))
- isAlignedCheck(x2, alignof(m256d))
- x1[] = set1(2.0 + a)
- x2[] = set1(-23.0 - b)
- let capturingLambda = proc(x: ref m256d): ref m256d =
- var cc = new(m256d)
- var bb = new(m256d)
- isAlignedCheck(x1, alignof(m256d))
- isAlignedCheck(x2, alignof(m256d))
- isAlignedCheck(cc, alignof(m256d))
- isAlignedCheck(bb, alignof(m256d))
- isAlignedCheck(z, alignof(m256d))
-
- cc[] = x1[] + x1[] + z[]
- bb[] = x2[] + set1(12.5) + z[]
-
- result = new(m256d)
- isAlignedCheck(result, alignof(m256d))
- result[] = cc[] + bb[] + x[]
-
- return capturingLambda
- var xx = new(m256d)
- xx[] = set1(10)
- isAlignedCheck(xx, alignOf(m256d))
- let f1 = lambdaGen(2.0 , 2.221, xx)
- let f2 = lambdaGen(-1.226 , 3.5, xx)
- isAlignedCheck(f1(xx), alignOf(m256d))
- isAlignedCheck(f2(xx), alignOf(m256d))
- #-----------------------------------------------------------------------------
- type
- MyAligned = object of RootObj
- a{.align: 128.}: float
- var f: MyAligned
- isAlignedCheck(f.addr, MyAligned.alignOf)
- var fref = new(MyAligned)
- isAlignedCheck(fref, MyAligned.alignOf)
- var fs: seq[MyAligned]
- var fr: seq[RootRef]
- for i in 0..1000:
- fs.add MyAligned()
- isAlignedCheck(fs[^1].addr, MyAligned.alignOf)
- fs[^1].a = i.float
- fr.add new(MyAligned)
- isAlignedCheck(fr[^1], MyAligned.alignOf)
- ((ref MyAligned)fr[^1])[].a = i.float
- for i in 0..1000:
- doAssert(fs[i].a == i.float)
- doAssert(((ref MyAligned)fr[i]).a == i.float)
- proc lambdaTest2(a: MyAligned, z: ref MyAligned): auto =
- var x1: MyAligned
- x1.a = a.a + z.a
- var x2: MyAligned
- x2.a = a.a - z.a
- let capturingLambda = proc(x: MyAligned): MyAligned =
- var cc: MyAligned
- var bb: MyAligned
- isAlignedCheck(x1.addr, MyAligned.alignOf)
- isAlignedCheck(x2.addr, MyAligned.alignOf)
- isAlignedCheck(cc.addr, MyAligned.alignOf)
- isAlignedCheck(bb.addr, MyAligned.alignOf)
- isAlignedCheck(z, MyAligned.alignOf)
-
- cc.a = x1.a + x1.a + z.a
- bb.a = x2.a - z.a
-
- isAlignedCheck(result.addr, MyAligned.alignOf)
- result.a = cc.a + bb.a + x2.a
-
- return capturingLambda
- let q1 = lambdaTest2(MyAligned(a: 1.0), (ref MyAligned)(a: 2.0))
- let q2 = lambdaTest2(MyAligned( a: -1.0), (ref MyAligned)(a: -2.0))
- isAlignedCheck(rawEnv(q1), MyAligned.alignOf)
- isAlignedCheck(rawEnv(q2), MyAligned.alignOf)
- discard q1(MyAligned(a: 1.0))
- discard q2(MyAligned(a: -1.0))
- #-----------------------------------------------------------------------------
- block:
- var s: seq[seq[MyAligned]]
- for len in 0..128:
- s.add newSeq[MyAligned](len)
- for i in 0..<len:
- s[^1][i] = MyAligned(a: 1.0)
- if len > 0:
- isAlignedCheck(s[^1][0].addr, MyAligned.alignOf)
-
- echo "y"
|