SE-0229 — SIMD Vectors

I think the names SIMD4 are strictly worse than the names Vector4, and I’m actually quite surprised that the core team would recommend this.

Instead of using the common mathematical term, it uses a niche computing term that describes semantics/implementation. Anybody with at least high school knowledge of math knows what a vector is. Much fewer people know what SIMD is.

I have yet to see a compelling argument for why the standard vector types in Swift should not have SIMD semantics. It seems to me that if you want to do vector arithmetic (most commonly in 2, 3 or 4 dimensions) these are the types you should use. And even if there are use cases where someone doesn’t want their vectors or matrices to be SIMD, should that really penalize the common case? That seems unprecedented in Swift naming, and definitely not in line with progressive disclosure.

I think this naming will have a very real effect: these types will be used less. People will not reach for them even when they should, because the names look daunting and strange.

7 Likes

I haven't participated in this review, but I'm no expert in SIMD and skimming the thread gave me the impression it was headed in a good direction so I left it alone. But now I feel something went wrong with the naming.

Removing "vector" from the name is a big mistake in my view.

If you look at the Wikipedia article on SIMD, vectors aren't even mentioned in the summary at the top. It's all general concepts of how computers parallelize data processing. Are people really expected to understand that SIMD4, which stands for "Single Instruction Multiple Data 4", is some kind of vector? That is pretty confused as a type name. One could even reasonably see the 4 as a version number (as in HTML5, SSE3, GCC4) or part of the acronym (as in UTF8, AMD64).

Is there a reason I'm missing why those types aren't a good enough base currency for mathematical vector types? I think it'll be sad when people fail to realize there are vector types available and instead build their own custom types or use tuples because "SIMD" is a weird name that means nothing to them. Also, if Swift is to have a type allowing library APIs to transact in vectors without having to each define their own custom type, I think it ought to have a better name than that.

8 Likes

Doc comments on these initializers mentioned the scalarCount property. It's an instance property -- how can an initializer depend on it (even in comments)?

Why not define an additional static scalarCount?

  /// Initialize from array literal
  ///
  /// Precondition: the array must have exactly scalarCount elements.
  init(arrayLiteral elements: Scalar...)
  
  /// Initialize from sequence
  ///
  /// Precondition: the sequence must have exactly scalarCount elements.
  init<S: Sequence>(_ elements: S) where S.Element == Scalar
2 Likes

The implementation first uses self.init() to create a vector with zero in all lanes. Then it copies scalars from the sequence, and checks if there have been too many/few elements. It can already access self.scalarCount at this point.

1 Like

There isn't a single major reason, but there are a few factors that mean we might want to consider something else for this purpose down the road. The biggest consideration is that the SIMD types support a pile of operations that abstract mathematical vectors do not. Mathematical vectors cannot be multiplied (and when they can, it's isn't necessarily pointwise), don't have a notion of lane-wise comparisons, etc. More generally, they may not even be finite-dimensional or have a notion of "components" with integer indices (though obviously, 2, 3, and 4-element vectors do).

These operations are generally useful, so even if use cases do not require them, having them is usually not harmful. But they do give some reason for pause.

Personally, I'm basically neutral on the subject. I think that either naming works fine semantically, and there are some nice things about both names. Ultimately, I don't think that it will matter that much (anecdotally, we've been using the convention simd_float4 and simd::float4 in the Obj-C and C++ SDK on Apple platforms for a few years[†], and we're not aware of lots of people being confused by the names there).

[†] originally these types were spelled vector_float4 and matrix_float4x4 in [Obj-]C. Having the uniform prefix simd_ was eventually judged to be a bigger win than spelling out matrix and vector, so they were renamed.

7 Likes

It doesn't seem to be necessary for anything, but it can always be added later.

The implementation is not what the user sees, however.

@scanon The shorter names of concrete types (e.g. SIMD64<T>) are good, but I wonder if the SIMD protocol should be renamed? Especially if there will be another protocol for matrices?

  • protocol SIMDScalar
  • protocol SIMDVector
  • protocol SIMDMatrix
1 Like

@benrimmington It's a fair question, but I think that either naming works fine, and one of them has already been approved.

The above makes a lot more sense to me than the (afaics) currently implied:

  • protocol SIMDScalar
  • protocol SIMD
  • protocol SIMDMatrix

I don't see how leaving out the "Vector"-part works fine in this (future) context.

1 Like

"SIMD" means that operations apply uniformly to all lanes. A SIMD matrix type would also be a SIMD vector.

What would m[3] mean for a SIMD4x3 matrix type?

I guess it would have to be very different from the current import simd-types:

import simd

var m = float4x3() // A matrix of 4 columns, each column is a float3
let fourthColumn: float3 = m[3]

since according to the proposed SIMD protocol, the subscript that takes an Int returns a Scalar which I assume would be Float rather than SIMD3<Float>?

(Related separate thread here.)

There will need to be a migration story if/when we map the existing C-language matrix types to something conforming to the new SIMD stuff. I expect that there will be a little bit of churn and mess, but nothing unreasonable. One plausible option would be to have these matrices imported from C expose a SIMD vector type view or member, rather than be a SIMD vector type themselves. There are some downsides to that too, and a number of other options to explore. I don't think that we've painted ourselves into any corners with the new protocols (at least, not beyond the constraints already existing from the SDK types).

It may be worth proactively deprecating the unlabeled subscript in favor of m[column: 3] to make some options smoother to adopt at some future point. I'll take a look at that.

1 Like

Is it possible to pass SIMD vectors as tuples?

Hi @elect86; please try to create new threads for new questions, especially for swift-evolution threads that have already completed their review.

In your new thread, it would be helpful if you can provide a bit more detail about what you're trying to do.

2 Likes