// RUN: %target-run-simple-swiftgyb // REQUIRES: executable_test // FIXME: No simd module on linux rdar://problem/20795411 // XFAIL: linux, windows import simd import StdlibUnittest % scalar_types = ['Float', 'Double', 'Int32', 'UInt32'] % float_types = ['Float', 'Double'] % ctype = { 'Float':'float', 'Double':'double', 'Int32':'int', 'UInt32':'uint'} % component = ['.x','.y','.z','.w'] % for type in scalar_types: % for cols in [2,3,4]: // Workaround % vectype = ctype[type] + str(cols) func same(_ x: ${vectype}, _ y: ${vectype}) -> Bool { for i in 0..<${cols} { // Workaround % if type in float_types: if x[i] != y[i] && !(x[i].isNaN && y[i].isNaN) { return false } % else: if x[i] != y[i] { return false } % end } return true } % if type in float_types: // Workaround % for rows in [2,3,4]: // Workaround % mattype = ctype[type] + str(cols) + 'x' + str(rows) func same(_ x: ${mattype}, _ y: ${mattype}) -> Bool { for i in 0..<${cols} { if !same(x[i], y[i]) { return false } } return true } % end # for rows in [2,3,4] % end # if type in float_types % end # for cols in [2,3,4] % end # for type in scalar_types /* func same(_ x:M, _ y:M) -> Bool { for i in 0 ..< x.columns { if (!same(x[i], y[i])) { return false } } return true } */ var simdTestSuite = TestSuite("simd") simdTestSuite.test("sizes") { // C interop requires that vector be the right size. expectEqual(8, MemoryLayout.size) expectEqual(16, MemoryLayout.size) expectEqual(16, MemoryLayout.size) expectEqual(8, MemoryLayout.size) expectEqual(16, MemoryLayout.size) expectEqual(16, MemoryLayout.size) expectEqual(16, MemoryLayout.size) expectEqual(32, MemoryLayout.size) expectEqual(32, MemoryLayout.size) expectEqual(16, MemoryLayout.size) expectEqual(32, MemoryLayout.size) expectEqual(32, MemoryLayout.size) expectEqual(24, MemoryLayout.size) expectEqual(48, MemoryLayout.size) expectEqual(48, MemoryLayout.size) expectEqual(32, MemoryLayout.size) expectEqual(64, MemoryLayout.size) expectEqual(64, MemoryLayout.size) expectEqual(32, MemoryLayout.size) expectEqual(64, MemoryLayout.size) expectEqual(64, MemoryLayout.size) expectEqual(48, MemoryLayout.size) expectEqual(96, MemoryLayout.size) expectEqual(96, MemoryLayout.size) expectEqual(64, MemoryLayout.size) expectEqual(128, MemoryLayout.size) expectEqual(128, MemoryLayout.size) } simdTestSuite.test("alignment") { struct GenericLayout { let t: T = 0 as! T let v: int4 = [1,2,3,4] } let g = GenericLayout() expectEqual(0, g.t) expectEqual([1,2,3,4], g.v) } simdTestSuite.test("vector init") { % for type in scalar_types: % for size in [2,3,4]: // Workaround % vectype = ctype[type] + str(size) % vec = 'v_' + vectype // Check empty initializer. var ${vec} = ${vectype}() expectEqualTest(${[0]*size}, ${vec}, sameValue: same) // Check literal initializer. ${vec} = ${vectype}(2) expectEqualTest(${[2]*size}, ${vec}, sameValue: same) // Check scalar initializer. expectEqualTest(${vectype}(${type}(2)), ${vec}, sameValue: same) // Check elementwise initializer. ${vec} = ${vectype}(${', '.join(map(lambda i: str(i), range(size)))}) expectEqualTest(${range(size)}, ${vec}, sameValue: same) // Check labeled elementwise initializer. ${vec} = ${vectype}(${', '.join(map(lambda i: component[i][1:] + ':' + str(i), range(size)))}) expectEqualTest(${range(size)}, ${vec}, sameValue: same) // Previous checks implicitly use the array initializer, so we're good // with that one already. % end # for size in [2,3,4] % end # for type in scalar_types } simdTestSuite.test("vector elements") { % for type in scalar_types: % for size in [2,3,4]: // Workaround % vectype = ctype[type] + str(size) % vec = 'v_' + vectype var ${vec} = ${vectype}() // Check getting and setting .xyzw % for i in range(size): ${vec + component[i]} = ${2*i} expectEqual(${vec + component[i]}, ${2*i}) % end // Check getting and setting [i] for i in 0..<${size} { ${vec}[i] = ${vec}[i]/2 } expectEqualTest(${vec}, ${range(size)}, sameValue: same) % end # for size in [2,3,4] % end # for type in scalar_types } % for type in scalar_types: // ---- % if type not in float_types: // ---- % for size in [2,3,4]: // ---- % vectype = ctype[type] + str(size) simdTestSuite.test("${vectype} wrapping arithmetic") { expectEqual(${vectype}(.max) &+ ${vectype}(1), ${vectype}(.min)) expectEqual(${vectype}(.min) &- ${vectype}(1), ${vectype}(.max)) expectEqual(${vectype}(.max) &* ${vectype}(.max), ${vectype}(1)) expectEqual(${vectype}(.max) &* .max, ${vectype}(1)) expectEqual(.max &* ${vectype}(.max), ${vectype}(1)) } % end % end % end simdTestSuite.test("vector distance") { % for type in float_types: let ${ctype[type]}2_x = ${ctype[type]}2(0,5) let ${ctype[type]}2_y = ${ctype[type]}2(3,1) expectEqual(5, distance(${ctype[type]}2_x, ${ctype[type]}2_y)) expectEqual(0, distance(${ctype[type]}2_x, ${ctype[type]}2_x)) expectEqual(25, distance_squared(${ctype[type]}2_x, ${ctype[type]}2_y)) expectEqual(0, distance_squared(${ctype[type]}2_x, ${ctype[type]}2_x)) let ${ctype[type]}3_x = ${ctype[type]}3(-1,-2,-4) let ${ctype[type]}3_y = ${ctype[type]}3( 1, 1, 2) expectEqual(7, distance(${ctype[type]}3_x, ${ctype[type]}3_y)) expectEqual(0, distance(${ctype[type]}3_x, ${ctype[type]}3_x)) expectEqual(49, distance_squared(${ctype[type]}3_x, ${ctype[type]}3_y)) expectEqual(0, distance_squared(${ctype[type]}3_x, ${ctype[type]}3_x)) let ${ctype[type]}4_x = ${ctype[type]}4(-1, 0, 1, 1) let ${ctype[type]}4_y = ${ctype[type]}4( 0, 1, 0, 2) expectEqual(2, distance(${ctype[type]}4_x, ${ctype[type]}4_y)) expectEqual(0, distance(${ctype[type]}4_x, ${ctype[type]}4_x)) expectEqual(4, distance_squared(${ctype[type]}4_x, ${ctype[type]}4_y)) expectEqual(0, distance_squared(${ctype[type]}4_x, ${ctype[type]}4_x)) % end # for type in float_types } simdTestSuite.test("matrix init") { % for type in float_types: % for cols in [2,3,4]: // Workaround % for rows in [2,3,4]: // Workaround % mattype = ctype[type] + str(cols) + 'x' + str(rows) % coltype = ctype[type] + str(rows) % mat = 'm_' + mattype % diagsize = rows if rows < cols else cols // Check empty initializer. var ${mat} = ${mattype}() expectEqualTest(${mat}, ${mattype}(${[[0]*rows]*cols}), sameValue: same) // Check scalar initializer. ${mat} = ${mattype}(2) for i in 0..<${rows} { for j in 0..<${cols} { if i == j { expectEqual(${mat}[i, i], 2) } else { expectEqual(${mat}[j, i], 0) } } } // Check diagonal initializer. ${mat} = ${mattype}(diagonal: ${range(diagsize)}) for i in 0..<${rows} { for j in 0..<${cols} { if i == j { expectEqual(${mat}[i, i], ${type}(i)) } else { expectEqual(${mat}[j, i], 0) } } } // All the previous checks implicitly used the column initializer. // Check row initializer. ${mat} = ${mattype}(rows:[ % for i in range(rows): ${range(i*cols, (i+1)*cols)}, % end # for i ]) for i in 0..<${rows} { for j in 0..<${cols} { expectEqual(${mat}[j, i], ${type}(${cols}*i + j)) } } % end # for rows % end # for cols % end # for type } simdTestSuite.test("matrix elements") { % for type in float_types: % for cols in [2,3,4]: // Workaround % for rows in [2,3,4]: // Workaround % mattype = ctype[type] + str(cols) + 'x' + str(rows) % coltype = ctype[type] + str(rows) % mat = 'm_' + mattype % basis = type.lower() + 'basis' + str(cols) + 'x' + str(rows) % diagsize = rows if rows < cols else cols // Check getting and setting columns. let ${basis} : [${coltype}] = [ % for i in range(cols): [${', '.join(map(lambda j: '1' if i == j else '0', range(rows)))}], % end ] var ${mat} = ${mattype}() for i in 0..<${cols} { ${mat}[i] = ${type}(i+1)*${basis}[i] } expectEqualTest( ${mat}, ${mattype}(diagonal:${range(1, diagsize + 1)}), sameValue: same) for i in 0..<${cols} { expectEqualTest(${mat}[i], ${type}(i + 1)*${basis}[i], sameValue: same) } // Check getting and setting elements (and transpose). ${mat} = ${mattype}() for i in 0..<${rows} { for j in 0..<${cols} { ${mat}[j, i] = ${type}(${cols}*i + j) } } var ${'trans'+mat} = ${mat}.transpose for j in 0..<${cols} { for i in 0..<${rows} { expectEqual(${'trans'+mat}[i, j], ${type}(${cols}*i + j)) } } % end # for rows % end # for cols % end # for type } simdTestSuite.test("debug description") { expectEqual("SIMD2(1.0, 2.5)", SIMD2(1.0, 2.5).debugDescription) } runAllTests()