File: SIMD.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (92 lines) | stat: -rw-r--r-- 2,897 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// RUN: %target-run-simple-swift
// REQUIRES: executable_test
// REQUIRES: objc_interop
// UNSUPPORTED: freestanding

import Foundation
import StdlibUnittest

let SIMDCodableTests = TestSuite("SIMDCodable")

// Round an integer to the closest representable JS integer value
func jsInteger<T>(_ value: T) -> T
where T : SIMD, T.Scalar : FixedWidthInteger {
  // Attempt to round-trip though Double; if that fails it's because the
  // rounded value is too large to fit in T, so use the largest value that
  // does fit instead.
  let upperBound = T.Scalar(Double(T.Scalar.max).nextDown)
  var result = T()
  for i in result.indices {
    result[i] = T.Scalar(exactly: Double(value[i])) ?? upperBound
  }
  return result
}

func testRoundTrip<T>(_ for: T.Type)
where T : SIMD, T.Scalar : FixedWidthInteger {
  let input = jsInteger(T.random(in: T.Scalar.min ... T.Scalar.max))
  let encoder = JSONEncoder()
  let decoder = JSONDecoder()
  do {
    let data = try encoder.encode(input)
    let output = try decoder.decode(T.self, from: data)
    expectEqual(input, output)
  }
  catch {
    expectUnreachableCatch(error)
  }
}

func testRoundTrip<T>(_ for: T.Type)
where T : SIMD, T.Scalar : BinaryFloatingPoint,
      T.Scalar.RawSignificand : FixedWidthInteger {
  let input = T.random(in: -16 ..< 16)
  let encoder = JSONEncoder()
  let decoder = JSONDecoder()
  do {
    let data = try encoder.encode(input)
    let output = try decoder.decode(T.self, from: data)
    expectEqual(input, output)
  }
  catch {
    expectUnreachableCatch(error)
  }
}

// Very basic round-trip test. We can be much more sophisticated in the future,
// but we want to at least exercise the API. Also need to add some negative
// tests for the error paths, and test a more substantial set of types.
SIMDCodableTests.test("roundTrip") {
  testRoundTrip(SIMD2<Int8>.self)
  testRoundTrip(SIMD3<Int8>.self)
  testRoundTrip(SIMD4<Int8>.self)
  testRoundTrip(SIMD2<UInt8>.self)
  testRoundTrip(SIMD3<UInt8>.self)
  testRoundTrip(SIMD4<UInt8>.self)
  testRoundTrip(SIMD2<Int32>.self)
  testRoundTrip(SIMD3<Int32>.self)
  testRoundTrip(SIMD4<Int32>.self)
  testRoundTrip(SIMD2<UInt32>.self)
  testRoundTrip(SIMD3<UInt32>.self)
  testRoundTrip(SIMD4<UInt32>.self)
  testRoundTrip(SIMD2<Int>.self)
  testRoundTrip(SIMD3<Int>.self)
  testRoundTrip(SIMD4<Int>.self)
  testRoundTrip(SIMD2<UInt>.self)
  testRoundTrip(SIMD3<UInt>.self)
  testRoundTrip(SIMD4<UInt>.self)
/* Apparently these fail to round trip not only for i386 but also on older
   macOS versions, so we'll disable them entirely for now.
#if !arch(i386)
  // https://github.com/apple/swift-corelibs-foundation/issues/3548
  testRoundTrip(SIMD2<Float>.self)
  testRoundTrip(SIMD3<Float>.self)
  testRoundTrip(SIMD4<Float>.self)
  testRoundTrip(SIMD2<Double>.self)
  testRoundTrip(SIMD3<Double>.self)
  testRoundTrip(SIMD4<Double>.self)
#endif
  */
}

runAllTests()