blob: afadc168a5286a66336a3d7398abac7b5893b33e [file] [log] [blame]
// RUN: %target-run-simple-swiftgyb
// REQUIRES: executable_test
// FIXME: No simd module on linux rdar://problem/20795411
// XFAIL: linux
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 <rdar://problem/18900352>
% vectype = ctype[type] + str(cols)
func same(_ x: ${vectype}, _ y: ${vectype}) -> Bool {
for i in 0..<${cols} {
// Workaround <rdar://problem/18900352>
% 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 <rdar://problem/18900352>
% for rows in [2,3,4]:
// Workaround <rdar://problem/18900352>
% 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<M: SIMDMatrixType>(_ 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<float2>.size)
expectEqual(16, MemoryLayout<float3>.size)
expectEqual(16, MemoryLayout<float4>.size)
expectEqual(8, MemoryLayout<int2>.size)
expectEqual(16, MemoryLayout<int3>.size)
expectEqual(16, MemoryLayout<int4>.size)
expectEqual(16, MemoryLayout<double2>.size)
expectEqual(32, MemoryLayout<double3>.size)
expectEqual(32, MemoryLayout<double4>.size)
expectEqual(16, MemoryLayout<float2x2>.size)
expectEqual(32, MemoryLayout<float2x3>.size)
expectEqual(32, MemoryLayout<float2x4>.size)
expectEqual(24, MemoryLayout<float3x2>.size)
expectEqual(48, MemoryLayout<float3x3>.size)
expectEqual(48, MemoryLayout<float3x4>.size)
expectEqual(32, MemoryLayout<float4x2>.size)
expectEqual(64, MemoryLayout<float4x3>.size)
expectEqual(64, MemoryLayout<float4x4>.size)
expectEqual(32, MemoryLayout<double2x2>.size)
expectEqual(64, MemoryLayout<double2x3>.size)
expectEqual(64, MemoryLayout<double2x4>.size)
expectEqual(48, MemoryLayout<double3x2>.size)
expectEqual(96, MemoryLayout<double3x3>.size)
expectEqual(96, MemoryLayout<double3x4>.size)
expectEqual(64, MemoryLayout<double4x2>.size)
expectEqual(128, MemoryLayout<double4x3>.size)
expectEqual(128, MemoryLayout<double4x4>.size)
}
simdTestSuite.test("alignment") {
struct GenericLayout<T> {
let t: T = 0 as! T
let v: int4 = [1,2,3,4]
}
let g = GenericLayout<Int>()
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 <rdar://problem/18900352>
% 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 <rdar://problem/18900352>
% 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 <rdar://problem/18900352>
% for rows in [2,3,4]:
// Workaround <rdar://problem/18900352>
% 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 <rdar://problem/18900352>
% for rows in [2,3,4]:
// Workaround <rdar://problem/18900352>
% 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
}
runAllTests()