Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Microsoft/CNTK into amita…
Browse files Browse the repository at this point in the history
…ga/parallelizationFix
  • Loading branch information
amitaga committed Mar 15, 2016
2 parents 0339ce7 + 41a05a5 commit 5f0ab1d
Show file tree
Hide file tree
Showing 19 changed files with 9,162 additions and 29 deletions.
41 changes: 41 additions & 0 deletions Source/ComputationNetworkLib/PreComputeNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,47 @@ class PerDimMeanVarNormalizationNode : public ComputationNode<ElemType>, public
Input(1)->ValidateInferInputDimsFrom(Input(0)->GetSampleLayout());
Input(2)->ValidateInferInputDimsFrom(Input(0)->GetSampleLayout());


#if 1
// support for legacy models when the mean and variance vectors were stored as column vectors (N,1)
// This code will copy the shape of Input(0) (source) to Input(1) and Input(2) (target) if:
// 1. The source is a 3-tensor with shape 1x1xM
// 2. The target is a vector (i.e., a 2-tensor with shape Nx1)
// 3. Both targets have the same number of elements
// 4. The number of elements in the target (N) is the same as the number of elements in the source (M)
// Note: This is somewhat ugly [Jasha Droppo].

auto dimsA = Input(0)->GetSampleLayout().GetDims();
auto dimsB = Input(1)->GetSampleLayout().GetDims();
auto dimsC = Input(2)->GetSampleLayout().GetDims();

if (
// Test condition 1.
(dimsA.size() == 3 && dimsA[0] == 1 && dimsA[1] == 1) &&
// Test condition 2.
(dimsB.size() == 2 && dimsB[1] == 1) &&
(dimsC.size() == 2 && dimsC[1] == 1) &&
// Test condition 3. and condition 4.
(dimsB[0] == dimsC[0] && dimsB[0] == dimsA[2])
)
{
// for error messages
string dimsBstring = string(Input(1)->GetSampleLayout());
string dimsCstring = string(Input(2)->GetSampleLayout());

// reshape Input(1)
Input(1)->SetDims(TensorShape(dimsA), false);
fprintf(stderr, "\n%ls %ls operation: For legacy compatibility, the sample layout of second input (%ls %ls operation) was patched to [%s] (from [%s])\n",
NodeName().c_str(), OperationName().c_str(), Input(1)->NodeName().c_str(), Input(1)->OperationName().c_str(), string(Input(1)->GetSampleLayout()).c_str(), dimsBstring.c_str());

// reshape Input(2)
Input(2)->SetDims(TensorShape(dimsA), false);
fprintf(stderr, "\n%ls %ls operation: For legacy compatibility, the sample layout of third input (%ls %ls operation) was patched to [%s] (from [%s])\n",
NodeName().c_str(), OperationName().c_str(), Input(2)->NodeName().c_str(), Input(2)->OperationName().c_str(), string(Input(2)->GetSampleLayout()).c_str(), dimsCstring.c_str());
}

#endif

if (isFinalValidationPass)
{
if (!Input(0)->GetSampleLayout().IsElementwiseCompatibleWith(Input(1)->GetSampleLayout()) || !Input(0)->GetSampleLayout().IsElementwiseCompatibleWith(Input(2)->GetSampleLayout()))
Expand Down
18 changes: 10 additions & 8 deletions Source/ComputationNetworkLib/SpecialPurposeNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,8 +701,8 @@ class DummyCriterionNode : public ComputationNodeNonLooping /*ComputationNode*/<
virtual void /*ComputationNodeNonLooping::*/ ForwardPropNonLooping() override
{
Value().VerifySize(1, 1);
Input(0)->Value().VerifySize(1, 1);
Value().SetValue(Input(0)->Value());
assert(Input(0)->Value().GetNumRows() == 1);
Value().SetValue(Input(0)->Value().SumOfElements());
#if NANCHECK
Value().HasNan("DummyCriterionNode");
#endif
Expand All @@ -715,15 +715,17 @@ class DummyCriterionNode : public ComputationNodeNonLooping /*ComputationNode*/<

if (Input(0)->OperationName() != L"InputValue")
LogicError("DummyCriterionNode criterion requires the first input to be computed objectives.");
if (Input(0)->OperationName() != L"InputValue")
LogicError("DummyCriterionNode criterion requires the first input to be computed derivatives.");
if (Input(1)->OperationName() != L"InputValue")
LogicError("DummyCriterionNode criterion requires the second input to be computed derivatives.");
if (isFinalValidationPass)
{
if (Input(0)->GetSampleMatrixNumRows() != 1)
LogicError("DummyCriterionNode criterion requires the first input to have dimension 1.");
if (Input(0)->GetSampleMatrixNumRows() == 0 || Input(1)->GetSampleMatrixNumRows() == 0 || Input(2)->GetSampleMatrixNumRows() == 0)
if (Input(0)->GetSampleMatrixNumRows() == 0
|| Input(1)->GetSampleMatrixNumRows() == 0
|| Input(2)->GetSampleMatrixNumRows() == 0)
LogicError("DummyCriterionNode operation: one of the operands has 0 elements.");
if (Input(1)->GetSampleMatrixNumRows() != Input(2)->GetSampleMatrixNumRows())
if (Input(1)->GetSampleMatrixNumRows() != Input(2)->GetSampleMatrixNumRows()
|| Input(0)->GetSampleMatrixNumCols() != Input(2)->GetSampleMatrixNumCols()
|| Input(1)->GetSampleMatrixNumCols() != Input(2)->GetSampleMatrixNumCols())
LogicError("The Matrix dimension in the DummyCriterionNode operation does not match.");
}

Expand Down
5 changes: 3 additions & 2 deletions Source/Math/GPUTensor.cu
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,10 @@ void LaunchUnaryTensorOp(ElemType beta, const ElemType* pa, ElemType* pb, ElemTy
#define CaseLaunchUnaryTensorOp(oper) \
case ElementWiseOperator::op##oper: \
if (beta == 0 && alpha == 1) \
return _launchUnaryTensorOp<ElemType, Functor##oper><<<grid.m_blocksPerGrid, grid.m_threadsPerBlock, 0, t_stream>>>(pa, pb, NN); \
_launchUnaryTensorOp<ElemType, Functor##oper><<<grid.m_blocksPerGrid, grid.m_threadsPerBlock, 0, t_stream>>>(pa, pb, NN); \
else \
return _launchUnaryTensorOp<ElemType, Functor##oper><<<grid.m_blocksPerGrid, grid.m_threadsPerBlock, 0, t_stream>>>(beta, pa, pb, alpha, NN);
_launchUnaryTensorOp<ElemType, Functor##oper><<<grid.m_blocksPerGrid, grid.m_threadsPerBlock, 0, t_stream>>>(beta, pa, pb, alpha, NN);\
break;

SyncGuard syncGuard;
GridDim grid(NN);
Expand Down
28 changes: 15 additions & 13 deletions Source/Readers/Kaldi2Reader/HTKMLFReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1405,10 +1405,10 @@ void HTKMLFReader<ElemType>::CopyMinibatchFromBufferToMatrix(
{
if (m_getMinibatchCopy)
{
if (data.GetNumCols() != m_currentMBSize * m_numberOfuttsPerMinibatch)
assert(m_currentMBSize * m_numberOfuttsPerMinibatch == m_pMBLayout->GetNumCols());
if (data.GetNumCols() != m_pMBLayout->GetNumCols())
{
matrices.GetInputMatrix<ElemType>(iter->first).Resize(data.GetNumRows(),
m_currentMBSize * m_numberOfuttsPerMinibatch);
data.Resize(data.GetNumRows(), m_pMBLayout->GetNumCols());
}
matrices.GetInputMatrix<ElemType>(iter->first).SetValue(0);
}
Expand All @@ -1423,15 +1423,17 @@ void HTKMLFReader<ElemType>::CopyMinibatchFromBufferToMatrix(
{
if (m_getMinibatchCopy)
{
if (data.GetNumCols() != 1)
assert(m_currentMBSize * m_numberOfuttsPerMinibatch == m_pMBLayout->GetNumCols());
if (data.GetNumCols() != m_pMBLayout->GetNumCols())
{
data.Resize(1, 1);
data.Resize(1, m_pMBLayout->GetNumCols());
}
data.SetValue(0);
}
else
{
m_uttDerivBuffer->GetObjective(m_minibatchUttInfo,
m_pMBLayout,
&matrices.GetInputMatrix<ElemType>(iter->first)); // TODO: use a reference instead of a ptr
}
}
Expand Down Expand Up @@ -1473,18 +1475,19 @@ void HTKMLFReader<ElemType>::CopyMinibatchToMatrix(
{
if (m_nameToTypeMap.at(iter->first) == InputOutputTypes::readerDeriv)
{
if (data.GetNumCols() != m_currentMBSize * m_numberOfuttsPerMinibatch)
assert(m_currentMBSize * m_numberOfuttsPerMinibatch == m_pMBLayout->GetNumCols());
if (data.GetNumCols() != m_pMBLayout->GetNumCols())
{
data.Resize(data.GetNumRows(),
m_currentMBSize * m_numberOfuttsPerMinibatch);
data.Resize(data.GetNumRows(), m_pMBLayout->GetNumCols());
}
data.SetValue(0);
}
else if (m_nameToTypeMap.at(iter->first) == InputOutputTypes::readerObj)
{
if (data.GetNumCols() != 1)
assert(m_currentMBSize * m_numberOfuttsPerMinibatch == m_pMBLayout->GetNumCols());
if (data.GetNumCols() != m_pMBLayout->GetNumCols())
{
data.Resize(1, 1);
data.Resize(1, m_pMBLayout->GetNumCols());
}
data.SetValue(0);
}
Expand Down Expand Up @@ -1589,8 +1592,7 @@ bool HTKMLFReader<ElemType>::GetMinibatchToWrite(StreamMinibatchInputs& matrices

// populate input matrices
bool first = true;
typename StreamMinibatchInputs::iterator iter;
for (iter = matrices.begin(); iter != matrices.end(); iter++)
for (auto iter = matrices.begin(); iter != matrices.end(); iter++)
{
// dereference matrix that corresponds to key (input/output name) and
// populate based on whether its a feature or a label
Expand Down Expand Up @@ -1907,7 +1909,7 @@ bool HTKMLFReader<ElemType>::SetNetOutput(
const MatrixBase& outputsb,
const MBLayoutPtr pMBLayout)
{
const auto& outputs = dymamic_cast<Matrix<ElemType>>(outputsb); // TODO: a NULL check, to be sure
const auto& outputs = dynamic_cast<const Matrix<ElemType>&>(outputsb); // TODO: a NULL check, to be sure
// Set the likelihoods for the utterance with which we can comput the
// derivatives. Note that the minibatch may only contain partial output
// for the utterance, <m_uttDerivBuffer> takes care of "gluing" them
Expand Down
2 changes: 0 additions & 2 deletions Source/Readers/Kaldi2Reader/HTKMLFWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ class HTKMLFWriter : public IDataWriter
};

public:
using LabelType = typename IDataWriter<ElemType>::LabelType;
using LabelIdType = typename IDataWriter<ElemType>::LabelIdType;
template <class ConfigRecordType>
void InitFromConfig(const ConfigRecordType& writerConfig);
virtual void Init(const ConfigParameters& config)
Expand Down
10 changes: 6 additions & 4 deletions Source/Readers/Kaldi2Reader/UtteranceDerivativeBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ bool UtteranceDerivativeBuffer<ElemType>::SetLikelihood(
ProcessUttInfo(uttInfo, pMBLayout, &uttInfoInMinibatch);

// Checks if we need to move data to CPU.
Matrix<ElemType> logLikelihood(logLikelihoodIn);
Matrix<ElemType> logLikelihood = logLikelihoodIn.DeepClone();
if (logLikelihood.GetDeviceId() >= 0)
{
logLikelihood.TransferFromDeviceToDevice(
Expand All @@ -114,7 +114,7 @@ bool UtteranceDerivativeBuffer<ElemType>::SetLikelihood(
tmpUttUnit.streamID = i;
tmpUttUnit.logLikelihood.Resize(logLikelihood.GetNumRows(),
tmpUttUnit.uttLength);
m_uttPool[uttID] = tmpUttUnit;
m_uttPool[uttID] = std::move(tmpUttUnit);
}

// Sets the likelihood and computes derivatives.
Expand Down Expand Up @@ -244,6 +244,7 @@ bool UtteranceDerivativeBuffer<ElemType>::GetDerivative(
template <class ElemType>
bool UtteranceDerivativeBuffer<ElemType>::GetObjective(
const std::vector<std::vector<std::pair<wstring, size_t>>>& uttInfo,
MBLayoutPtr pMBLayout,
Matrix<ElemType>* objectivesIn)
{
assert(objectivesIn != NULL);
Expand All @@ -258,8 +259,9 @@ bool UtteranceDerivativeBuffer<ElemType>::GetObjective(
}

// Sets the objectives...
objectivesIn->Resize(1, 1);
objectivesIn->SetValue(m_currentObj);
objectivesIn->Resize(1, pMBLayout->GetNumCols());
objectivesIn->SetValue(
m_currentObj / static_cast<ElemType>(pMBLayout->GetNumCols()));

return true;
}
Expand Down
2 changes: 2 additions & 0 deletions Source/Readers/Kaldi2Reader/UtteranceDerivativeBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class UtteranceDerivativeBuffer
progress = 0;
streamID = 0;
}

};

bool m_needLikelihood;
Expand Down Expand Up @@ -87,6 +88,7 @@ class UtteranceDerivativeBuffer
// Gets the computed objectives for given utterance.
bool GetObjective(
const std::vector<std::vector<std::pair<wstring, size_t>>>& uttInfo,
const MBLayoutPtr pMBLayout,
Matrix<ElemType>* objectivesIn);

bool HasResourceForDerivative(const wstring& uttID) const;
Expand Down
Binary file added Tests/EndToEndTests/Speech/Data/glob_0000.ark
Binary file not shown.
Loading

0 comments on commit 5f0ab1d

Please sign in to comment.