-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
WIP: Typed array encoding in supplyDefaults with Caching #5308
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
Changes from all commits
67ccac9
712a124
4d5b382
7233f34
5079fc7
38e10bb
1043827
8d84f3e
2381deb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,8 @@ | |
*/ | ||
|
||
'use strict'; | ||
var b64 = require('base64-arraybuffer'); | ||
var isPlainObject = require('./is_plain_object'); | ||
|
||
var isArray = Array.isArray; | ||
|
||
|
@@ -63,6 +65,112 @@ exports.ensureArray = function(out, n) { | |
return out; | ||
}; | ||
|
||
var typedArrays = { | ||
int8: typeof Int8Array !== 'undefined' ? Int8Array : null, | ||
uint8: typeof Uint8Array !== 'undefined' ? Uint8Array : null, | ||
uint8clamped: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : null, | ||
int16: typeof Int16Array !== 'undefined' ? Int16Array : null, | ||
uint16: typeof Uint16Array !== 'undefined' ? Uint16Array : null, | ||
int32: typeof Int32Array !== 'undefined' ? Int32Array : null, | ||
uint32: typeof Uint32Array !== 'undefined' ? Uint32Array : null, | ||
float32: typeof Float32Array !== 'undefined' ? Float32Array : null, | ||
float64: typeof Float64Array !== 'undefined' ? Float64Array : null, | ||
}; | ||
exports.typedArrays = typedArrays; | ||
|
||
|
||
exports.decodeTypedArraySpec = function(v) { | ||
// Assume processed by coerceTypedArraySpec | ||
v = coerceTypedArraySpec(v); | ||
var T = typedArrays[v.dtype]; | ||
var buffer; | ||
if(v.bvals.constructor === ArrayBuffer) { | ||
// Already an ArrayBuffer | ||
buffer = v.bvals; | ||
} else { | ||
// Decode, assuming a string | ||
buffer = b64.decode(v.bvals); | ||
} | ||
|
||
// Check if 1d shape. If so, we're done | ||
if(v.ndims === 1) { | ||
// Construct single Typed array over entire buffer | ||
return new T(buffer); | ||
} else { | ||
// Reshape into nested plain arrays with innermost | ||
// level containing typed arrays | ||
// We could eventually adopt an ndarray library | ||
|
||
// Build cumulative product of dimensions | ||
var cumulativeShape = v.shape.map(function(a, i) { | ||
return a * (v.shape[i - 1] || 1); | ||
}); | ||
|
||
// Loop of dimensions in reverse order | ||
var nestedArray = []; | ||
for(var dimInd = v.ndims - 1; dimInd > 0; dimInd--) { | ||
var subArrayLength = v.shape[dimInd]; | ||
var numSubArrays = cumulativeShape[dimInd - 1]; | ||
var nextArray = []; | ||
|
||
if(dimInd === v.ndims - 1) { | ||
// First time through, we build the | ||
// inner most typed arrays | ||
for(var typedInd = 0; typedInd < numSubArrays; typedInd++) { | ||
var typedOffset = typedInd * subArrayLength; | ||
nextArray.push( | ||
new T(buffer, typedOffset * T.BYTES_PER_ELEMENT, subArrayLength) | ||
); | ||
} | ||
} else { | ||
// Following times through, build | ||
// next layer of nested arrays | ||
for(var i = 0; i < numSubArrays; i++) { | ||
var offset = i * subArrayLength; | ||
nextArray.push(nextArray.slice(offset, offset + subArrayLength - 1)); | ||
} | ||
} | ||
|
||
// Update nested array with next nesting level | ||
nestedArray = nextArray; | ||
} | ||
|
||
return nestedArray; | ||
} | ||
}; | ||
|
||
function isTypedArraySpec(v) { | ||
// Assume v has not passed through | ||
return isPlainObject(v) && typedArrays[v.dtype] && v.bvals && ( | ||
Number.isInteger(v.shape) || | ||
(isArrayOrTypedArray(v.shape) && | ||
v.shape.length > 0 && | ||
v.shape.every(function(d) { return Number.isInteger(d); })) | ||
); | ||
} | ||
exports.isTypedArraySpec = isTypedArraySpec; | ||
|
||
function coerceTypedArraySpec(v) { | ||
// Assume isTypedArraySpec passed | ||
var coerced = {dtype: v.dtype, bvals: v.bvals}; | ||
|
||
// Normalize shape to a list | ||
if(Number.isInteger(v.shape)) { | ||
coerced.shape = [v.shape]; | ||
} else { | ||
coerced.shape = v.shape; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be a good idea to drop this array support for shape attribute; while it cannot be a typedArray itself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the moment, I am using the shape to build a multi-dimensional array when the length is more than 1. Only the inner most layer of the multi-dimensional array is made up of typed arrays, but I pretty sure it'll be a lot better than nothing. |
||
} | ||
|
||
// Add length property | ||
coerced.length = v.shape.reduce(function(a, b) { return a * b; }); | ||
|
||
// Add ndims | ||
coerced.ndims = v.shape.length; | ||
|
||
return coerced; | ||
} | ||
exports.coerceTypedArraySpec = coerceTypedArraySpec; | ||
|
||
/* | ||
* TypedArray-compatible concatenation of n arrays | ||
* if all arrays are the same type it will preserve that type, | ||
|
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.
Could we possibly support numeric strings here as well?