import { computeStrides, sizeFromShape } from '../util'; /** * Check whether updates.shape = indices.shape[:batchDim] + * shape[sliceDim:] * * @param x The input tensor. */ export function validateUpdateShape(shape, indices, updates) { const sliceDim = (indices.rank > 1) ? indices.shape[indices.rank - 1] : 1; const batchDim = (indices.rank > 1) ? indices.rank - 1 : 1; const shapeError = 'Must have updates.shape = indices.shape[:batchDim] + ' + `shape[sliceDim:], got updates.shape: ${updates.shape}` + `, indices.shape: ${indices.shape}, shape: ${shape}` + `, sliceDim: ${sliceDim}, and batchDim: ${batchDim}.`; if (updates.rank < batchDim) { throw new Error(shapeError + ` update.rank < ${batchDim}. `); } if (shape.length < sliceDim + (updates.rank - batchDim)) { throw new Error(shapeError + ` Output shape length < ${sliceDim + (updates.rank - batchDim)}`); } if (updates.rank !== batchDim + shape.length - sliceDim) { throw new Error(shapeError + ` update.rank != ${batchDim + shape.length - sliceDim}`); } for (let d = 0; d < batchDim; ++d) { if (updates.shape[d] !== indices.shape[d]) { throw new Error(shapeError + ` updates.shape[${d}] (${updates.shape[d]}) != indices.shape[${d}] (${indices.shape[d]}).`); } } for (let d = 0; d < updates.rank - batchDim; ++d) { if (updates.shape[d + batchDim] !== shape[d + sliceDim]) { throw new Error(shapeError + ` updates.shape[${d + batchDim}] (${updates.shape[d + batchDim]}) != shape[${d + batchDim}] (${shape[d + batchDim]})`); } } } /** * Validate scatter nd inputs. * * @param update The tensor contains the update values. * @param indices The tensor contains the indices for the update values. * @param shape The shape of the output tensor. */ export function validateInput(updates, indices, shape) { if (indices.rank < 1) { throw new Error('tf.scatterND() expects the indices to be rank 1 or higher,' + ` but the rank was ${indices.rank}.`); } if (updates.rank < 1) { throw new Error('tf.scatterND() expects the updates to be rank 1 or higher,' + ` but the rank was ${updates.rank}.`); } if (indices.dtype !== 'int32') { throw new Error(`The dtype of 'indices' should be int32, but got dtype: ${indices.dtype}`); } if (shape.length < 1) { throw new Error(`Output rank must be greater or equal to 1, but got shape: ${shape}`); } if (shape.length === 0) { if (indices.size === 0) { throw new Error(`Indices specified for empty output. indices shape: ${indices.shape}`); } if (updates.size === 0) { throw new Error(`Updates specified for empty output. updates shape: ${updates.shape}`); } } validateUpdateShape(shape, indices, updates); } /** * Calculate the shape information for the output. * * @param update The tensor contains the update values. * @param indices The tensor contains the indices for the update values. * @param shape The shape of the output tensor. * * @returns ScatterShapeInfo */ export function calculateShapes(updates, indices, shape) { // Calculate the number of dimensions in indices const indicesRank = indices.shape.length; const sliceRank = (indicesRank > 1) ? indices.shape[indicesRank - 1] : 1; // Calculate the number of elements that make up each slice of our updated // tensor. This allows us to work with flattened tensors and copy over whole // slices at a time. const totalNd = shape.length; let sliceSize = 1; for (let i = sliceRank; i < totalNd; ++i) { sliceSize *= shape[i]; } const safeSliceDim = (sliceRank < 1) ? 1 : sliceRank; const numUpdates = sizeFromShape(indices.shape) / safeSliceDim; const strides = [...computeStrides(shape.slice(0, sliceRank)), 1]; const outputSize = sizeFromShape(shape); return { sliceRank, numUpdates, sliceSize, strides, outputSize }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhdHRlcl9uZF91dGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvc2NhdHRlcl9uZF91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQSxPQUFPLEVBQUMsY0FBYyxFQUFFLGFBQWEsRUFBQyxNQUFNLFNBQVMsQ0FBQztBQUV0RDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDL0IsS0FBZSxFQUFFLE9BQWUsRUFBRSxPQUFlO0lBQ25ELE1BQU0sUUFBUSxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUUsTUFBTSxRQUFRLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRTNELE1BQU0sVUFBVSxHQUFHLHVEQUF1RDtRQUN0RSx3Q0FBd0MsT0FBTyxDQUFDLEtBQUssRUFBRTtRQUN2RCxvQkFBb0IsT0FBTyxDQUFDLEtBQUssWUFBWSxLQUFLLEVBQUU7UUFDcEQsZUFBZSxRQUFRLG1CQUFtQixRQUFRLEdBQUcsQ0FBQztJQUUxRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLEdBQUcsUUFBUSxFQUFFO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxHQUFHLGtCQUFrQixRQUFRLElBQUksQ0FBQyxDQUFDO0tBQzlEO0lBQ0QsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLFFBQVEsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUU7UUFDdkQsTUFBTSxJQUFJLEtBQUssQ0FDWCxVQUFVO1lB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cmlnaHQgMjAxOCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5pbXBvcnQgeyBUZW5zb3JJbmZvIH0gZnJvbSAnLi4vdGVuc29yX2luZm8nO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uL3RlbnNvcic7XG5pbXBvcnQge2NvbXB1dGVTdHJpZGVzLCBzaXplRnJvbVNoYXBlfSBmcm9tICcuLi91dGlsJztcblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIHVwZGF0ZXMuc2hhcGUgPSBpbmRpY2VzLnNoYXBlWzpiYXRjaERpbV0gK1xuICogc2hhcGVbc2xpY2VEaW06XVxuICpcbiAqIEBwYXJhbSB4IFRoZSBpbnB1dCB0ZW5zb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVVwZGF0ZVNoYXBlKFxuICAgIHNoYXBlOiBudW1iZXJbXSwgaW5kaWNlczogVGVuc29yLCB1cGRhdGVzOiBUZW5zb3IpIHtcbiAgY29uc3Qgc2xpY2VEaW0gPSAoaW5kaWNlcy5yYW5rID4gMSkgPyBpbmRpY2VzLnNoYXBlW2luZGljZXMucmFuayAtIDFdIDogMTtcbiAgY29uc3QgYmF0Y2hEaW0gPSAoaW5kaWNlcy5yYW5rID4gMSkgPyBpbmRpY2VzLnJhbmsgLSAxIDogMTtcblxuICBjb25zdCBzaGFwZUVycm9yID0gJ011c3QgaGF2ZSB1cGRhdGVzLnNoYXBlID0gaW5kaWNlcy5zaGFwZVs6YmF0Y2hEaW1dICsgJyArXG4gICAgICBgc2hhcGVbc2xpY2VEaW06XSwgZ290IHVwZGF0ZXMuc2hhcGU6ICR7dXBkYXRlcy5zaGFwZX1gICtcbiAgICAgIGAsIGluZGljZXMuc2hhcGU6ICR7aW5kaWNlcy5zaGFwZX0sIHNoYXBlOiAke3NoYXBlfWAgK1xuICAgICAgYCwgc2xpY2VEaW06ICR7c2xpY2VEaW19LCBhbmQgYmF0Y2hEaW06ICR7YmF0Y2hEaW19LmA7XG5cbiAgaWYgKHVwZGF0ZXMucmFuayA8IGJhdGNoRGltKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKHNoYXBlRXJyb3IgKyBgIHVwZGF0ZS5yYW5rIDwgJHtiYXRjaERpbX0uIGApO1xuICB9XG4gIGlmIChzaGFwZS5sZW5ndGggPCBzbGljZURpbSArICh1cGRhdGVzLnJhbmsgLSBiYXRjaERpbSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIHNoYXBlRXJyb3IgK1xuICAgICAgICBgIE91dHB1dCBzaGFwZSBsZW5ndGggPCAke3NsaWNlRGltICsgKHVwZGF0ZXMucmFuayAtIGJhdGNoRGltKX1gKTtcbiAgfVxuICBpZiAodXBkYXRlcy5yYW5rICE9PSBiYXRjaERpbSArIHNoYXBlLmxlbmd0aCAtIHNsaWNlRGltKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBzaGFwZUVycm9yICsgYCB1cGRhdGUucmFuayAhPSAke2JhdGNoRGltICsgc2hhcGUubGVuZ3RoIC0gc2xpY2VEaW19YCk7XG4gIH1cbiAgZm9yIChsZXQgZCA9IDA7IGQgPCBiYXRjaERpbTsgKytkKSB7XG4gICAgaWYgKHVwZGF0ZXMuc2hhcGVbZF0gIT09IGluZGljZXMuc2hhcGVbZF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBzaGFwZUVycm9yICtcbiAgICAgICAgICBgIHVwZGF0ZXMuc2hhcGVbJHtkfV0gKCR7dXBkYXRlcy5zaGFwZVtkXX0pICE9IGluZGljZXMuc2hhcGVbJHtkfV0gKCR7XG4gICAgICAgICAgICAgIGluZGljZXMuc2hhcGVbZF19KS5gKTtcbiAgICB9XG4gIH1cbiAgZm9yIChsZXQgZCA9IDA7IGQgPCB1cGRhdGVzLnJhbmsgLSBiYXRjaERpbTsgKytkKSB7XG4gICAgaWYgKHVwZGF0ZXMuc2hhcGVbZCArIGJhdGNoRGltXSAhPT0gc2hhcGVbZCArIHNsaWNlRGltXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIHNoYXBlRXJyb3IgK1xuICAgICAgICAgIGAgdXBkYXRlcy5zaGFwZVske2QgKyBiYXRjaERpbX1dICgke1xuICAgICAgICAgICAgICB1cGRhdGVzLnNoYXBlW2QgKyBiYXRjaERpbV19KSAhPSBzaGFwZVske2QgKyBiYXRjaERpbX1dICgke1xuICAgICAgICAgICAgICBzaGFwZVtkICsgYmF0Y2hEaW1dfSlgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBTY2F0dGVyU2hhcGVJbmZvIHtcbiAgc2xpY2VSYW5rOiBudW1iZXI7XG4gIG51bVVwZGF0ZXM6IG51bWJlcjtcbiAgc2xpY2VTaXplOiBudW1iZXI7XG4gIHN0cmlkZXM6IG51bWJlcltdO1xuICBvdXRwdXRTaXplOiBudW1iZXI7XG59XG4vKipcbiAqIFZhbGlkYXRlIHNjYXR0ZXIgbmQgaW5wdXRzLlxuICpcbiAqIEBwYXJhbSB1cGRhdGUgVGhlIHRlbnNvciBjb250YWlucyB0aGUgdXBkYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSBpbmRpY2VzIFRoZSB0ZW5zb3IgY29udGFpbnMgdGhlIGluZGljZXMgZm9yIHRoZSB1cGRhdGUgdmFsdWVzLlxuICogQHBhcmFtIHNoYXBlIFRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IHRlbnNvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlSW5wdXQoXG4gICAgdXBkYXRlczogVGVuc29yLCBpbmRpY2VzOiBUZW5zb3IsIHNoYXBlOiBudW1iZXJbXSkge1xuICBpZiAoaW5kaWNlcy5yYW5rIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ3RmLnNjYXR0ZXJORCgpIGV4cGVjdHMgdGhlIGluZGljZXMgdG8gYmUgcmFuayAxIG9yIGhpZ2hlciwnICtcbiAgICAgICAgYCBidXQgdGhlIHJhbmsgd2FzICR7aW5kaWNlcy5yYW5rfS5gKTtcbiAgfVxuICBpZiAodXBkYXRlcy5yYW5rIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ3RmLnNjYXR0ZXJORCgpIGV4cGVjdHMgdGhlIHVwZGF0ZXMgdG8gYmUgcmFuayAxIG9yIGhpZ2hlciwnICtcbiAgICAgICAgYCBidXQgdGhlIHJhbmsgd2FzICR7dXBkYXRlcy5yYW5rfS5gKTtcbiAgfVxuICBpZiAoaW5kaWNlcy5kdHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGR0eXBlIG9mICdpbmRpY2VzJyBzaG91bGQgYmUgaW50MzIsIGJ1dCBnb3QgZHR5cGU6ICR7XG4gICAgICAgIGluZGljZXMuZHR5cGV9YCk7XG4gIH1cbiAgaWYgKHNoYXBlLmxlbmd0aCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBPdXRwdXQgcmFuayBtdXN0IGJlIGdyZWF0ZXIgb3IgZXF1YWwgdG8gMSwgYnV0IGdvdCBzaGFwZTogJHtzaGFwZX1gKTtcbiAgfVxuXG4gIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaW5kaWNlcy5zaXplID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEluZGljZXMgc3BlY2lmaWVkIGZvciBlbXB0eSBvdXRwdXQuIGluZGljZXMgc2hhcGU6ICR7XG4gICAgICAgICAgaW5kaWNlcy5zaGFwZX1gKTtcbiAgICB9XG4gICAgaWYgKHVwZGF0ZXMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVcGRhdGVzIHNwZWNpZmllZCBmb3IgZW1wdHkgb3V0cHV0LiB1cGRhdGVzIHNoYXBlOiAke1xuICAgICAgICAgIHVwZGF0ZXMuc2hhcGV9YCk7XG4gICAgfVxuICB9XG5cbiAgdmFsaWRhdGVVcGRhdGVTaGFwZShzaGFwZSwgaW5kaWNlcywgdXBkYXRlcyk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBzaGFwZSBpbmZvcm1hdGlvbiBmb3IgdGhlIG91dHB1dC5cbiAqXG4gKiBAcGFyYW0gdXBkYXRlIFRoZSB0ZW5zb3IgY29udGFpbnMgdGhlIHVwZGF0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0gaW5kaWNlcyBUaGUgdGVuc29yIGNvbnRhaW5zIHRoZSBpbmRpY2VzIGZvciB0aGUgdXBkYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSBzaGFwZSBUaGUgc2hhcGUgb2YgdGhlIG91dHB1dCB0ZW5zb3IuXG4gKlxuICogQHJldHVybnMgU2NhdHRlclNoYXBlSW5mb1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlU2hhcGVzKFxuICAgIHVwZGF0ZXM6IFRlbnNvckluZm8sIGluZGljZXM6IFRlbnNvckluZm8sXG4gICAgc2hhcGU6IG51bWJlcltdKTogU2NhdHRlclNoYXBlSW5mbyB7XG4gIC8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGRpbWVuc2lvbnMgaW4gaW5kaWNlc1xuICBjb25zdCBpbmRpY2VzUmFuayA9IGluZGljZXMuc2hhcGUubGVuZ3RoO1xuICBjb25zdCBzbGljZVJhbmsgPSAoaW5kaWNlc1JhbmsgPiAxKSA/IGluZGljZXMuc2hhcGVbaW5kaWNlc1JhbmsgLSAxXSA6IDE7XG5cbiAgLy8gQ2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgdGhhdCBtYWtlIHVwIGVhY2ggc2xpY2Ugb2Ygb3VyIHVwZGF0ZWRcbiAgLy8gdGVuc29yLiBUaGlzIGFsbG93cyB1cyB0byB3b3JrIHdpdGggZmxhdHRlbmVkIHRlbnNvcnMgYW5kIGNvcHkgb3ZlciB3aG9sZVxuICAvLyBzbGljZXMgYXQgYSB0aW1lLlxuICBjb25zdCB0b3RhbE5kID0gc2hhcGUubGVuZ3RoO1xuXG4gIGxldCBzbGljZVNpemUgPSAxO1xuICBmb3IgKGxldCBpID0gc2xpY2VSYW5rOyBpIDwgdG90YWxOZDsgKytpKSB7XG4gICAgc2xpY2VTaXplICo9IHNoYXBlW2ldO1xuICB9XG5cbiAgY29uc3Qgc2FmZVNsaWNlRGltID0gKHNsaWNlUmFuayA8IDEpID8gMSA6IHNsaWNlUmFuaztcbiAgY29uc3QgbnVtVXBkYXRlcyA9IHNpemVGcm9tU2hhcGUoaW5kaWNlcy5zaGFwZSkgLyBzYWZlU2xpY2VEaW07XG5cbiAgY29uc3Qgc3RyaWRlcyA9IFsuLi5jb21wdXRlU3RyaWRlcyhzaGFwZS5zbGljZSgwLCBzbGljZVJhbmspKSwgMV07XG4gIGNvbnN0IG91dHB1dFNpemUgPSBzaXplRnJvbVNoYXBlKHNoYXBlKTtcbiAgcmV0dXJuIHtzbGljZVJhbmssIG51bVVwZGF0ZXMsIHNsaWNlU2l6ZSwgc3RyaWRlcywgb3V0cHV0U2l6ZX07XG59XG4iXX0=