NDMaskPtr NDMask::DeepClone(const DeviceDescriptor& device) const { NDMaskPtr newMask = MakeSharedObject<NDMask>(this->Shape(), device); newMask->CopyFrom(*this); return newMask; }
NDMaskPtr NDMask::DeepClone() const { NDMaskPtr newMask = MakeSharedObject<NDMask>(this->Shape(), this->Device()); newMask->CopyFrom(*this); return newMask; }
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; }
NDMaskPtr NDMask::DeepClone() const { NDMaskPtr newMask = new NDMask(this->Shape(), this->Device()); newMask->CopyFrom(*this); return NDMaskPtr(newMask, [](ReferenceCount* ptr) { delete ptr; }); }
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; }
/*static*/ ValuePtr Value::Create(const NDShape& sampleShape, const std::vector<std::vector<ElementType>>& sequences, const DeviceDescriptor& device, bool readOnly/* = false*/) { size_t sampleSize = sampleShape.TotalSize(); NDMaskPtr deviceValueMask = CreateMask(sampleSize, sequences, device); size_t maxSequenceLength = (deviceValueMask == nullptr) ? sequences[0].size() : deviceValueMask->Shape()[0]; size_t numSequences = sequences.size(); NDShape valueDataShape = sampleShape.AppendShape({ maxSequenceLength, numSequences }); NDArrayViewPtr valueData(new NDArrayView(AsDataType<ElementType>(), valueDataShape, DeviceDescriptor::CPUDevice()), [](ReferenceCount* ptr) { delete ptr; }); ElementType* dataBuffer = valueData->WritableDataBuffer<ElementType>(); for (size_t i = 0; i < numSequences; ++i) std::copy(sequences[i].data(), sequences[i].data() + sequences[i].size(), dataBuffer + (maxSequenceLength * i * sampleSize)); NDArrayViewPtr deviceValueData; if (device == DeviceDescriptor::CPUDevice()) { if (readOnly) deviceValueData = valueData->Alias(true); else deviceValueData = valueData; } else { deviceValueData = NDArrayViewPtr(new NDArrayView(AsDataType<ElementType>(), valueDataShape, device), [](ReferenceCount* ptr) { delete ptr; }); deviceValueData->CopyFrom(*valueData); if (readOnly) deviceValueData = deviceValueData->Alias(true); } return ValuePtr(new Value(deviceValueData, deviceValueMask), [](ReferenceCount* ptr) { delete ptr; }); }
/*static*/ ValuePtr Value::Create(size_t vocabularySize, const std::vector<std::vector<size_t>>& oneHotSequences, const DeviceDescriptor& device, bool readOnly/* = false*/) { NDMaskPtr deviceValueMask = CreateMask(1, oneHotSequences, device); size_t maxSequenceLength = (deviceValueMask == nullptr) ? oneHotSequences[0].size() : deviceValueMask->Shape()[0]; size_t numSequences = oneHotSequences.size(); NDShape sampleShape = { vocabularySize }; NDShape valueDataShape = sampleShape.AppendShape({ maxSequenceLength, numSequences }); size_t numCSCCols = valueDataShape.SubShape(1).TotalSize() + 1; std::vector<SparseIndexType> colStarts(numCSCCols); std::vector<ElementType> nonZeroValues; std::vector<SparseIndexType> rowIndices; for (size_t i = 0; i < numSequences; ++i) { size_t currentSequenceLength = oneHotSequences[i].size(); size_t j = 0; for (; j < currentSequenceLength; ++j) { colStarts[(i * maxSequenceLength) + j] = (SparseIndexType)nonZeroValues.size(); nonZeroValues.push_back(1); rowIndices.push_back((SparseIndexType)(oneHotSequences[i][j])); } for (; j < maxSequenceLength; ++j) colStarts[(i * maxSequenceLength) + j] = (SparseIndexType)(nonZeroValues.size()); } colStarts[numSequences * maxSequenceLength] = (SparseIndexType)(nonZeroValues.size()); NDArrayViewPtr deviceValueData(new NDArrayView(valueDataShape, colStarts.data(), rowIndices.data(), nonZeroValues.data(), nonZeroValues.size(), device, readOnly), [](ReferenceCount* ptr) { delete ptr; }); return ValuePtr(new Value(deviceValueData, deviceValueMask), [](ReferenceCount* ptr) { delete ptr; }); }
Value::Value(const NDArrayViewPtr& data, const NDMaskPtr& mask) : m_data(data), m_mask(mask) { if (mask != nullptr) { auto dataShape = data->Shape(); auto maskShape = mask->Shape(); if (maskShape.NumAxes() > dataShape.NumAxes()) InvalidArgument("The number of axes of the mask of a Value object cannot exceed the number of axes of the data NDArrayView object"); if (dataShape.SubShape(dataShape.NumAxes() - maskShape.NumAxes()) != maskShape) InvalidArgument("Invalid Value object; the data and mask are incompatible. The trailing dimensions of the data do not match the dimensions of the mask"); } }
Value::Value(const NDArrayViewPtr& data, const NDMaskPtr& mask) : m_data(data), m_mask(mask) { if (mask != nullptr) { auto dataShape = data->Shape(); auto maskShape = mask->Shape(); if (maskShape.Rank() > dataShape.Rank()) InvalidArgument("The rank (%d) of the mask of a Value object cannot exceed the rank (%d) of the data NDArrayView object", (int)maskShape.Rank(), (int)dataShape.Rank()); if (dataShape.SubShape(dataShape.Rank() - maskShape.Rank()) != maskShape) InvalidArgument("Invalid Value object; the data and mask are incompatible. The trailing dimensions of the data with shape %S do not match the dimensions of the mask with shape %S", AsStringForErrorReporting(dataShape).c_str(), AsStringForErrorReporting(maskShape).c_str()); } }