mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This is the second part of 308f39fe56.
It fixes (better: works-around) linker errors when testing in optimized mode.
352 lines
10 KiB
Plaintext
352 lines
10 KiB
Plaintext
// RUN: rm -f %t.swift %t.out
|
|
|
|
// RUN: %S/../../utils/gyb %s -o %t.swift
|
|
// RUN: %S/../../utils/line-directive %t.swift -- %target-build-swift %t.swift -o %t.out
|
|
// RUN: %S/../../utils/line-directive %t.swift -- %target-run %t.out
|
|
// REQUIRES: executable_test
|
|
|
|
// FIXME: No simd module on linux rdar://problem/20795411
|
|
// XFAIL: linux
|
|
|
|
import simd
|
|
import StdlibUnittest
|
|
|
|
// Also import modules which are used by StdlibUnittest internally. This
|
|
// workaround is needed to link all required libraries in case we compile
|
|
// StdlibUnittest with -sil-serialize-all.
|
|
import SwiftPrivate
|
|
#if _runtime(_ObjC)
|
|
import ObjectiveC
|
|
#endif
|
|
|
|
% scalar_types = ['Float', 'Double', 'Int32']
|
|
% float_types = ['Float', 'Double']
|
|
% ctype = { 'Float':'float', 'Double':'double', 'Int32':'int' }
|
|
% 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, sizeof(float2.self))
|
|
expectEqual(16, sizeof(float3.self))
|
|
expectEqual(16, sizeof(float4.self))
|
|
expectEqual(8, sizeof(int2.self))
|
|
expectEqual(16, sizeof(int3.self))
|
|
expectEqual(16, sizeof(int4.self))
|
|
expectEqual(16, sizeof(double2.self))
|
|
expectEqual(32, sizeof(double3.self))
|
|
expectEqual(32, sizeof(double4.self))
|
|
|
|
expectEqual(16, sizeof(float2x2.self))
|
|
expectEqual(32, sizeof(float2x3.self))
|
|
expectEqual(32, sizeof(float2x4.self))
|
|
expectEqual(24, sizeof(float3x2.self))
|
|
expectEqual(48, sizeof(float3x3.self))
|
|
expectEqual(48, sizeof(float3x4.self))
|
|
expectEqual(32, sizeof(float4x2.self))
|
|
expectEqual(64, sizeof(float4x3.self))
|
|
expectEqual(64, sizeof(float4x4.self))
|
|
|
|
expectEqual(32, sizeof(double2x2.self))
|
|
expectEqual(64, sizeof(double2x3.self))
|
|
expectEqual(64, sizeof(double2x4.self))
|
|
expectEqual(48, sizeof(double3x2.self))
|
|
expectEqual(96, sizeof(double3x3.self))
|
|
expectEqual(96, sizeof(double3x4.self))
|
|
expectEqual(64, sizeof(double4x2.self))
|
|
expectEqual(128, sizeof(double4x3.self))
|
|
expectEqual(128, sizeof(double4x4.self))
|
|
}
|
|
|
|
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}()
|
|
expectEqual(${[0]*size}, ${vec}, sameValue: same)
|
|
|
|
// Check literal initializer.
|
|
${vec} = ${vectype}(2)
|
|
expectEqual(${[2]*size}, ${vec}, sameValue: same)
|
|
|
|
// Check scalar initializer.
|
|
expectEqual(${vectype}(${type}(2)), ${vec}, sameValue: same)
|
|
|
|
// Check elementwise initializer.
|
|
${vec} = ${vectype}(${', '.join(map(lambda i: str(i), range(size)))})
|
|
expectEqual(${range(size)}, ${vec}, sameValue: same)
|
|
|
|
// Check labeled elementwise initializer.
|
|
${vec} = ${vectype}(${', '.join(map(lambda i:
|
|
component[i][1:] + ':' + str(i),
|
|
range(size)))})
|
|
expectEqual(${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]} = ${-i}
|
|
expectEqual(${vec + component[i]}, ${-i})
|
|
% end
|
|
|
|
// Check getting and setting [i]
|
|
for i in 0..<${size} { ${vec}[i] = -${vec}[i] }
|
|
expectEqual(${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)
|
|
|
|
extension ${vectype}: Equatable {}
|
|
public func ==(a: ${vectype}, b: ${vectype}) -> Bool {
|
|
% for i in xrange(0, size):
|
|
if (a${component[i]} != b${component[i]}) { return false }
|
|
% end
|
|
return true
|
|
}
|
|
|
|
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 debugDescription") {
|
|
var f2 = float2(1, 2)
|
|
expectEqual("float2(1.0, 2.0)", f2.debugDescription)
|
|
var f3 = float3(1, 2, 3)
|
|
expectEqual("float3(1.0, 2.0, 3.0)", f3.debugDescription)
|
|
var f4 = float4(1, 2, 3, 4)
|
|
expectEqual("float4(1.0, 2.0, 3.0, 4.0)", f4.debugDescription)
|
|
|
|
var d2 = double2(1, 2)
|
|
expectEqual("double2(1.0, 2.0)", d2.debugDescription)
|
|
var d3 = double3(1, 2, 3)
|
|
expectEqual("double3(1.0, 2.0, 3.0)", d3.debugDescription)
|
|
var d4 = double4(1, 2, 3, 4)
|
|
expectEqual("double4(1.0, 2.0, 3.0, 4.0)", d4.debugDescription)
|
|
|
|
var i2 = int2(1, 2)
|
|
expectEqual("int2(1, 2)", i2.debugDescription)
|
|
var i3 = int3(1, 2, 3)
|
|
expectEqual("int3(1, 2, 3)", i3.debugDescription)
|
|
var i4 = int4(1, 2, 3, 4)
|
|
expectEqual("int4(1, 2, 3, 4)", i4.debugDescription)
|
|
}
|
|
|
|
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}()
|
|
expectEqual(${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))
|
|
}
|
|
}
|
|
|
|
// Round-trip through C matrix type.
|
|
expectEqual(${mat}, ${mattype}(${mat}.cmatrix), sameValue: same)
|
|
|
|
% 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]
|
|
}
|
|
expectEqual(
|
|
${mat}, ${mattype}(diagonal:${range(1,diagsize+1)}), sameValue: same)
|
|
for i in 0..<${cols} {
|
|
expectEqual(${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()
|
|
|