Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃敤 refactor: dims checks for inputs and outputs #102

Merged
merged 12 commits into from
Aug 2, 2023
2 changes: 1 addition & 1 deletion .swiftpm/xcode/xcshareddata/xcschemes/GrAIdient.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.

## [unreleased]

馃敤 **refactor:** dims checks for inputs and outputs ([#102](https://github.com/owkin/GrAIdient/pull/102))\
馃獪 **feat:** BCE1D, BCE2D, VQ2D & VQSeq as losses ([#101](https://github.com/owkin/GrAIdient/pull/101))\
馃獪 **layer_seq:** VQSeq ([#100](https://github.com/owkin/GrAIdient/pull/100))\
馃敤 **layer_2d:** expose indices in VQ2D ([#99](https://github.com/owkin/GrAIdient/pull/99))\
Expand Down
158 changes: 104 additions & 54 deletions Sources/GrAIdient/Layer1D/BCE1D.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,35 @@ public class BCE1D: LayerOutput1D
///
/// Estimate the gradients of weights thanks to Gradient Checking.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameter groundTruth: The ground truth.
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
/// - Returns: The estimated gradients of weights.
///
public func collectGradientsApprox<T: BinaryFloatingPoint>(
_ groundTruth: [[T]]) throws -> [T]
_ groundTruth: [[T]],
batchSize: Int,
nbNeurons: Int) throws -> [T]
{
var gradients = [T]()
let nbGradients = neurons.get(0)!.nbGC / 2
for elem in 0..<nbGradients
{
let loss1 = try getLossGC(groundTruth, elem: 2 * elem)
let loss2 = try getLossGC(groundTruth, elem: 2 * elem + 1)
let loss1 = try getLossGC(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons,
elem: 2 * elem
)
let loss2 = try getLossGC(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons,
elem: 2 * elem + 1
)

let gradient = (loss1 - loss2) / T(2 * 茞)
gradients.append(gradient)
Expand All @@ -65,23 +80,26 @@ public class BCE1D: LayerOutput1D
///
/// Get the loss consecutive of a modified weights during the Gradient Checking process.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
/// - elem: The modified weight for which we collect the resulting loss.
/// - Returns: The loss value.
///
func getLossGC<T: BinaryFloatingPoint>(
_ groundTruth: [[T]],
batchSize: Int,
nbNeurons: Int,
elem: Int) throws -> T
{
let batchSize = groundTruth.count
if batchSize != self.batchSize ||
batchSize <= 0 || batchSize > neurons.get(0)!.v.count
{
throw LayerError.BatchSize
}
try checkGroundTruthCPU(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons
)

var losses = [T](repeating: 0.0, count: batchSize)
for batch in 0..<batchSize
Expand All @@ -108,20 +126,24 @@ public class BCE1D: LayerOutput1D
///
/// Get loss in the CPU execution context.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameter groundTruth: The ground truth.
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
/// - Returns: The loss value.
///
public func getLossCPU<T: BinaryFloatingPoint>(
_ groundTruth: [[T]]) throws -> T
_ groundTruth: [[T]],
batchSize: Int,
nbNeurons: Int) throws -> T
{
let batchSize = groundTruth.count
if batchSize != self.batchSize ||
batchSize <= 0 || batchSize > neurons.get(0)!.v.count
{
throw LayerError.BatchSize
}
try checkGroundTruthCPU(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons
)

var losses = [T](repeating: 0.0, count: batchSize)
for elem in 0..<batchSize
Expand All @@ -148,41 +170,53 @@ public class BCE1D: LayerOutput1D
///
/// Get loss in the GPU execution context.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameter groundTruth: The ground truth.
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
/// - Returns: The loss value.
///
public func getLossGPU<T: BinaryFloatingPoint>(
_ groundTruth: [[T]]) throws -> T
_ groundTruth: [[T]],
batchSize: Int,
nbNeurons: Int) throws -> T
{
try checkGroundTruthGPU(groundTruth)

try checkGroundTruthGPU(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons
)
return try T(getLossGPU(
self.groundTruth,
batchSize: groundTruth.count
batchSize: groundTruth.count,
nbNeurons: nbNeurons
))
}

///
/// Get loss in the GPU execution context.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
/// - Returns: The loss value.
///
public func getLossGPU(
_ groundTruth: MetalBuffer<Float>,
batchSize: Int) throws -> Float
batchSize: Int,
nbNeurons: Int) throws -> Float
{
try checkGroundTruthGPU(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons
)
try checkLossGPU(batchSize: batchSize)
if batchSize != self.batchSize
{
throw LayerError.BatchSize
}

let pNbNeurons: [UInt32] = [UInt32(nbNeurons)]
let pNbBatch: [UInt32] = [UInt32(batchSize)]
Expand Down Expand Up @@ -218,19 +252,23 @@ public class BCE1D: LayerOutput1D
/// The `setData` API sets data to the first layer to initialize the forward pass.
/// Here we use the `groundTruth` to initialize the backward pass.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameter groundTruth: The ground truth.
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
///
public func lossDerivativeCPU<T: BinaryFloatingPoint>(
_ groundTruth: [[T]]) throws
_ groundTruth: [[T]],
batchSize: Int,
nbNeurons: Int) throws
{
let batchSize = groundTruth.count
if batchSize != self.batchSize ||
batchSize <= 0 || batchSize > neurons.get(0)!.v.count
{
throw LayerError.BatchSize
}
try checkGroundTruthCPU(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons
)

if let layerPrev = self.layerPrev as? Layer1D, mustComputeBackward
{
Expand Down Expand Up @@ -288,18 +326,27 @@ public class BCE1D: LayerOutput1D
/// The `setData` API sets data to the first layer to initialize the forward pass.
/// Here we use the `groundTruth` to initialize the backward pass.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameter groundTruth: The ground truth.
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
///
public func lossDerivativeGPU<T: BinaryFloatingPoint>(
_ groundTruth: [[T]]) throws
_ groundTruth: [[T]],
batchSize: Int,
nbNeurons: Int) throws
{
try checkGroundTruthGPU(groundTruth)

try checkGroundTruthGPU(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons
)
try lossDerivativeGPU(
self.groundTruth,
batchSize: groundTruth.count
batchSize: groundTruth.count,
nbNeurons: nbNeurons
)
}

Expand All @@ -312,20 +359,23 @@ public class BCE1D: LayerOutput1D
/// The `setData` API sets data to the first layer to initialize the forward pass.
/// Here we use the `groundTruth` to initialize the backward pass.
///
/// Throw an error if batch size or ground truth are incoherent.
/// Throw an error if data size is incoherent.
///
/// - Parameters:
/// - groundTruth: The ground truth.
/// - batchSize: The batch size of data.
/// - nbNeurons: Number of neurons.
///
public func lossDerivativeGPU(
_ groundTruth: MetalBuffer<Float>,
batchSize: Int) throws
batchSize: Int,
nbNeurons: Int) throws
{
if batchSize != self.batchSize
{
throw LayerError.BatchSize
}
try checkGroundTruthGPU(
groundTruth,
batchSize: batchSize,
nbNeurons: nbNeurons
)

if let layerPrev = self.layerPrev as? Layer1D, mustComputeBackward
{
Expand Down
Loading