mirror of
https://github.com/wassname/keras-js.git
synced 2026-09-11 12:20:53 +08:00
additional fallback to CPU when tensor MAX_TEXTURE_SIZE exceeded (#8)
This commit is contained in:
@@ -248,7 +248,7 @@ export default class Convolution3D extends Layer {
|
||||
const nbPatches = outputDim1 * outputDim2 * outputDim3
|
||||
const matMul = new Tensor([], [nbPatches, nbFilter])
|
||||
|
||||
if (this._useWeblas) {
|
||||
if (this._useWeblas && !(this._volColsMat._gpuMaxSizeExceeded || this._wRowsMat._gpuMaxSizeExceeded)) {
|
||||
const bias = this.bias ? this.weights.b.weblasTensor : this._zerosVec.weblasTensor
|
||||
matMul.tensor.data = weblas.pipeline.sgemm(
|
||||
1, this._volColsMat.weblasTensor, this._wRowsMat.weblasTensor,
|
||||
|
||||
@@ -185,7 +185,7 @@ export default class Deconvolution2D extends Layer {
|
||||
const [nbFilter, nbRow, nbCol] = this.kernelShape
|
||||
const matMul = new Tensor([], [inputRows * inputCols, nbRow * nbCol * nbFilter])
|
||||
|
||||
if (this._useWeblas) {
|
||||
if (this._useWeblas && !(imColsMat._gpuMaxSizeExceeded || this._wRowsMat._gpuMaxSizeExceeded)) {
|
||||
let _zerosVec = new Tensor([], [this.weights.W.tensor.shape[3]])
|
||||
_zerosVec.createWeblasTensor()
|
||||
matMul.tensor.data = weblas.pipeline.sgemm(
|
||||
|
||||
@@ -81,58 +81,28 @@ class _DepthwiseConvolution2D extends Convolution2D {
|
||||
* @returns {Tensor} x
|
||||
*/
|
||||
call (x) {
|
||||
let startTime = performance.now()
|
||||
this._calcOutputShape(x)
|
||||
let endTime = performance.now()
|
||||
console.log(0, endTime - startTime)
|
||||
startTime = performance.now()
|
||||
this._padInput(x)
|
||||
endTime = performance.now()
|
||||
console.log(1, endTime - startTime)
|
||||
|
||||
startTime = performance.now()
|
||||
this._im2col(x)
|
||||
endTime = performance.now()
|
||||
console.log(2, endTime - startTime)
|
||||
|
||||
startTime = performance.now()
|
||||
const nbFilter = this.kernelShape[0]
|
||||
const outputRows = this.outputShape[0]
|
||||
const outputCols = this.outputShape[1]
|
||||
const nbPatches = outputRows * outputCols
|
||||
const matMul = new Tensor([], [nbPatches * x.tensor.shape[2], nbFilter * x.tensor.shape[2]])
|
||||
endTime = performance.now()
|
||||
console.log(3, endTime - startTime)
|
||||
|
||||
startTime = performance.now()
|
||||
if (this._useWeblas) {
|
||||
if (this._useWeblas && !(this._imColsMat._gpuMaxSizeExceeded || this._wRowsMat._gpuMaxSizeExceeded)) {
|
||||
// GPU
|
||||
if (this._imColsMat.weblasTensorsSplit) {
|
||||
// split matrix multiply if this._imColsMat dimension > webgl.MAX_TEXTURE_SIZE
|
||||
let offset = 0
|
||||
this._imColsMat.weblasTensorsSplit.forEach(imColsMatSplit => {
|
||||
const matMulSplitData = weblas.pipeline.sgemm(
|
||||
1, imColsMatSplit, this._wRowsMat.weblasTensor,
|
||||
1, this._zerosVec.weblasTensor
|
||||
).transfer()
|
||||
matMul.tensor.data.set(matMulSplitData, offset)
|
||||
offset += matMulSplitData.length
|
||||
})
|
||||
} else {
|
||||
// normal matrix multiply
|
||||
matMul.tensor.data = weblas.pipeline.sgemm(
|
||||
1, this._imColsMat.weblasTensor, this._wRowsMat.weblasTensor,
|
||||
1, this._zerosVec.weblasTensor
|
||||
).transfer()
|
||||
}
|
||||
matMul.tensor.data = weblas.pipeline.sgemm(
|
||||
1, this._imColsMat.weblasTensor, this._wRowsMat.weblasTensor,
|
||||
1, this._zerosVec.weblasTensor
|
||||
).transfer()
|
||||
} else {
|
||||
// CPU
|
||||
gemm(matMul.tensor, this._imColsMat.tensor, this._wRowsMat.tensor, 1, 1)
|
||||
}
|
||||
endTime = performance.now()
|
||||
console.log(4, endTime - startTime)
|
||||
|
||||
startTime = performance.now()
|
||||
let output = new Tensor([], [outputRows, outputCols, x.tensor.shape[2] * nbFilter])
|
||||
const outputDataLength = outputRows * outputCols * x.tensor.shape[2] * nbFilter
|
||||
let dataFiltered = new Float32Array(outputDataLength)
|
||||
@@ -144,8 +114,6 @@ class _DepthwiseConvolution2D extends Convolution2D {
|
||||
}
|
||||
}
|
||||
output.replaceTensorData(dataFiltered)
|
||||
endTime = performance.now()
|
||||
console.log(5, endTime - startTime)
|
||||
|
||||
x.tensor = output.tensor
|
||||
|
||||
@@ -233,10 +201,7 @@ export default class SeparableConvolution2D extends Layer {
|
||||
const depthwiseOutput = this._depthwiseConv.call(x)
|
||||
|
||||
// Perform depthwise ops
|
||||
let startTime = performance.now()
|
||||
const pointwiseOutput = this._pointwiseConv.call(depthwiseOutput)
|
||||
let endTime = performance.now()
|
||||
console.log(6, endTime - startTime)
|
||||
|
||||
x.tensor = pointwiseOutput.tensor
|
||||
|
||||
|
||||
@@ -77,6 +77,9 @@ export default class Dense extends Layer {
|
||||
|
||||
if (this._useWeblas) {
|
||||
x.createWeblasTensor()
|
||||
}
|
||||
|
||||
if (this._useWeblas && !(x._gpuMaxSizeExceeded || this.weights.W._gpuMaxSizeExceeded)) {
|
||||
const bias = this.bias ? this.weights.b.weblasTensor : this._zerosVec.weblasTensor
|
||||
y.tensor.data = weblas.pipeline.sgemm(
|
||||
1, x.weblasTensor, this.weights.W.weblasTensor,
|
||||
|
||||
Reference in New Issue
Block a user