static NDMaskPtr CreateMask(size_t sampleSize, const std::vector<std::vector<T>>& sequences, const DeviceDescriptor& device) { size_t numSequences = sequences.size(); std::vector<size_t> sequenceLengths(numSequences); size_t maxSequenceLength = 0; bool needsMask = false; for (size_t i = 0; i < numSequences; ++i) { sequenceLengths[i] = sequences[i].size() / sampleSize; if (maxSequenceLength < sequenceLengths[i]) maxSequenceLength = sequenceLengths[i]; if ((i > 0) && (sequenceLengths[i - 1] != sequenceLengths[i])) needsMask = true; } NDMaskPtr deviceValueMask; if (needsMask) { NDShape valueMaskShape = { maxSequenceLength, numSequences }; deviceValueMask = NDMaskPtr(new NDMask(valueMaskShape, device), [](Internal::ReferenceCount* ptr) {delete ptr; }); for (size_t i = 0; i < numSequences; ++i) deviceValueMask->MaskSection({ sequenceLengths[i], i }, { NDShape::InferredDimension, 1 }); } return deviceValueMask; }
static NDMaskPtr CreateMask(size_t numElementsPerSample, const std::vector<std::vector<T>>& sequences, const DeviceDescriptor& device) { size_t numSequences = sequences.size(); std::vector<size_t> sequenceLengths(numSequences); size_t maxSequenceLength = 0; bool needsMask = false; for (size_t i = 0; i < numSequences; ++i) { sequenceLengths[i] = sequences[i].size() / numElementsPerSample; if (maxSequenceLength < sequenceLengths[i]) maxSequenceLength = sequenceLengths[i]; if ((i > 0) && (sequenceLengths[i - 1] != sequenceLengths[i])) needsMask = true; } // If needed, create a mask to account for variability in lengths of specified sequences NDMaskPtr deviceValueMask; if (needsMask) { NDShape valueMaskShape = { maxSequenceLength, numSequences }; deviceValueMask = MakeSharedObject<NDMask>(valueMaskShape, device); for (size_t i = 0; i < numSequences; ++i) { deviceValueMask->MarkSequenceBegin({0, i}); deviceValueMask->InvalidateSection({ sequenceLengths[i], i }, { NDShape::InferredDimension, 1 }); } } return deviceValueMask; }