-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split #16
base: main
Are you sure you want to change the base?
Split #16
Conversation
Not sure if you mean subscript or something else, but if you mean subscript we do have an impl for that
|
/// takes a shape for the original array, a shape for the subarray, | ||
/// and an axis on which the original array would be divided | ||
/// and returns an array of start and end indices for each subarray | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For doc comments, let's use both starting capitalization and ending punctuation. also // helper function
is missing an /
/// and returns an array of start and end indices for each subarray | ||
|
||
@usableFromInline | ||
internal func _calculateSubarrayIndices(shape: [Int], subarrayShape: [Int], axis: Int) -> [SubarrayIndices] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only use of the_
prefix for a name is for public
identifiers such as public protocol _ShapedArrayProtocol
because they need to be public
to work yet we want to signal to the user that they shouldn't be used directly. For non-public
identifiers I think we should omit _
, in this case that would be calculateSubarrayIndices
.
However, i think we can improve on the name more too. Possibly
slicedSubArrayIndices(forShape shape: [Int], subarrayShape: [Int], alongAxis axis: Int) -> [SubarrayIndices]
?
Lastly, and maybe this isn't possible with @usableFromInline
, but if this is only used in 1 function I usually move the function declaration inside of the function that uses it. It adds some indentation but makes it clear at point of use that it isn't used elsewhere. Up to you though, nbd either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe splitSubArrayIndices
to match the calling function..
internal func _calculateSubarrayIndices(shape: [Int], subarrayShape: [Int], axis: Int) -> [SubarrayIndices] { | ||
let numberOfSubarrays = shape[axis] / subarrayShape[axis] | ||
|
||
var subarrays = [SubarrayIndices]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to think of a name that better captures this type, maybe var groupedSubarrayIndices
? any suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slicedSubarrayIndices
?
endIndices[axis] = startIndices[axis] + subarrayShape[axis] | ||
|
||
subarrays.append(SubarrayIndices(start: startIndices, end: endIndices)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this may look a bit nicer with a map
let subarrays = (0..<numberSubarrays).map { i in
var startIndices = [Int](repeating: 0, count: shape.count)
var endIndices = shape
startIndices[axis] = i * subarrayShape[axis]
endIndices[axis] = startIndices[axis] + subarrayShape[axis]
return SubarrayIndices(start: startIndices, end: endIndices)
}
} | ||
|
||
// helper function for subarray indices generation | ||
/// takes a start and end index for each dimension and returns all the n-dim indices in between |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as before about doc comments.
/// Splits the ShapedArray into multiple subarrays along the given axis. | ||
/// - Parameters: | ||
/// - count: The number of subarrays to return. | ||
/// - axis: The axis along which to split the ShapedArray. Negative values wrap around. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- axis
seems misaligned with - count
// helper function for subarray indices generation | ||
/// takes a start and end index for each dimension and returns all the n-dim indices in between | ||
@usableFromInline | ||
internal func _generateIndices(start: [Int], end: [Int], currentIndex: [Int] = [], depth: Int = 0) -> [[Int]] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
allIndices(fromStart start: [Int], toEnd end: [Int], currentIndices: [Int] = [], depth: Int = 0) -> [[Int]]
|
||
for i in start[depth]..<end[depth] { | ||
let newIndex = currentIndex + [i] | ||
let subIndices = _generateIndices(start: start, end: end, currentIndex: newIndex, depth: depth + 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't tail recursive so there's no tail-call optimization. Granted probably plenty to optimize in the future, but maybe add a comment here calling that out explicitly?
E.g. TODO: Possible tail-call optimization
?
} | ||
|
||
// helper function for subarray indices generation | ||
/// takes a shape, strides, and n-dim indices and returns the linear index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
// helper function for subarray indices generation | ||
/// takes a shape, strides, and n-dim indices and returns the linear index | ||
@usableFromInline | ||
internal func _calculateLinearIndex(shape: [Int], strides: [Int], indices: [Int]) -> Int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
linearIndexFrom(shape: [Int], strides: [Int], indices: [Int]) -> Int
?
other option may be bufferIndexFrom(shape:strides:indices)
} | ||
linearIndex += stride * index | ||
} | ||
return linearIndex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation is very off here...
return linearIndex | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only 1 newline please
return newArrays | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only 1 newline please
@@ -70,15 +183,17 @@ extension ShapedArray { | |||
/// - Precondition: `axis` must be in the range `[-rank, rank)`, where `rank` is the rank of | |||
/// the provided ShapedArrays. | |||
/// | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both newlines here should be deleted please, this breaks up the comment
@@ -318,3 +318,14 @@ extension _ShapedArrayProtocol where Scalar: Equatable { | |||
} | |||
} | |||
} | |||
|
|||
extension _ShapedArrayProtocol where Scalar: Comparable { | |||
internal func _isLess(than other: Self) -> Bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this function used anywhere, is this something we need to keep?
|
||
} | ||
|
||
// test expandingShape |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment here probably not needed since it's in the name of the test function
@@ -99,6 +214,47 @@ extension ShapedArray { | |||
|
|||
return newArrays.map { ShapedArray(shape: newShape, scalars: $0) } | |||
} | |||
|
|||
@inlinable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some docs we can include:
/// Returns a shape-expanded `ShapedArray`, with a dimension of 1 inserted at the specified shape
/// indices.
} | ||
|
||
@inlinable | ||
public func rankLifted() -> ShapedArray { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible docs for this:
/// Returns a rank-lifted `ShapedArray` with a leading dimension of 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for this! left some comments before approval, but nothing major
Split function and other basic function such as expandingShape and squeezingShape. I think there is a much better implementation for the split function but this is what I came up with. It uses a few helper functions. These helper functions could also be used for subscription. In fact, if subscription was implemented, split could have been implemented very straightforwardly.