Merge pull request #743 from danpovey/cygwin-fix

some changes to fix compilation issues on cygwin: broke up kws-functi…
This commit is contained in:
Daniel Povey 2016-05-07 16:22:24 -04:00
Родитель 4614e176ed 371a3cee34
Коммит 83031f2ce9
6 изменённых файлов: 211 добавлений и 171 удалений

Просмотреть файл

@ -6,7 +6,7 @@ include ../kaldi.mk
EXTRA_CXXFLAGS += -Wno-sign-compare
OBJFILES = kws-functions.o kws-scoring.o
OBJFILES = kws-functions.o kws-functions2.o kws-scoring.o
LIBNAME = kaldi-kws
ADDLIBS = ../hmm/kaldi-hmm.a ../lat/kaldi-lat.a ../tree/kaldi-tree.a \

Просмотреть файл

@ -23,6 +23,10 @@
#include "fstext/determinize-star.h"
#include "fstext/epsilon-property.h"
// note: this .cc file does not include everything declared in kws-functions.h;
// the remainder are defined in kws-functions2.cc (for compilation speed and
// to avoid generating too-large object files on cygwin).
namespace kaldi {
bool CompareInterval(const Interval &i1,
@ -139,39 +143,10 @@ class CompactLatticeToKwsProductFstMapper {
uint64 Properties(uint64 props) const { return props; }
};
class KwsProductFstToKwsLexicographicFstMapper {
public:
typedef KwsProductArc FromArc;
typedef KwsProductWeight FromWeight;
typedef KwsLexicographicArc ToArc;
typedef KwsLexicographicWeight ToWeight;
KwsProductFstToKwsLexicographicFstMapper() {}
ToArc operator()(const FromArc &arc) const {
return ToArc(arc.ilabel,
arc.olabel,
(arc.weight == FromWeight::Zero() ?
ToWeight::Zero() :
ToWeight(arc.weight.Value1().Value(),
StdLStdWeight(arc.weight.Value2().Value1().Value(),
arc.weight.Value2().Value2().Value()))),
arc.nextstate);
}
fst::MapFinalAction FinalAction() const { return fst::MAP_NO_SUPERFINAL; }
fst::MapSymbolsAction InputSymbolsAction() const { return fst::MAP_COPY_SYMBOLS; }
fst::MapSymbolsAction OutputSymbolsAction() const { return fst::MAP_COPY_SYMBOLS;}
uint64 Properties(uint64 props) const { return props; }
};
bool CreateFactorTransducer(const CompactLattice &clat,
const vector<int32> &state_times,
int32 utterance_id,
int32 utterance_id,
KwsProductFst *factor_transducer) {
using namespace fst;
typedef KwsProductArc::StateId StateId;
@ -196,10 +171,10 @@ bool CreateFactorTransducer(const CompactLattice &clat,
// initial and remove the total weight, i.e., the sum of all the outgoing
// transitions and final weight at any state is equal to One() (push only the
// negated log-prob, not the alignments)
for (StateIterator<KwsProductFst>
for (StateIterator<KwsProductFst>
siter(*factor_transducer); !siter.Done(); siter.Next()) {
KwsProductArc::StateId state_id = siter.Value();
for (MutableArcIterator<KwsProductFst>
for (MutableArcIterator<KwsProductFst>
aiter(factor_transducer, state_id); !aiter.Done(); aiter.Next()) {
KwsProductArc arc = aiter.Value();
BaseFloat w = arc.weight.Value1().Value();
@ -213,7 +188,7 @@ bool CreateFactorTransducer(const CompactLattice &clat,
BaseFloat w = factor_transducer->Final(state_id).Value1().Value();
w += beta[state_id];
KwsProductWeight weight(w, factor_transducer->Final(state_id).Value2());
factor_transducer->SetFinal(state_id, weight);
factor_transducer->SetFinal(state_id, weight);
}
}
@ -248,11 +223,11 @@ bool CreateFactorTransducer(const CompactLattice &clat,
if (!has_epsilon_property) {
KALDI_WARN << "Epsilon property does not hold, reverting to old behavior.";
}
// OK, after the above preparation, we finally come to the factor generation
// step.
StateId ns = factor_transducer->NumStates();
StateId ss = factor_transducer->AddState();
// step.
StateId ns = factor_transducer->NumStates();
StateId ss = factor_transducer->AddState();
StateId fs = factor_transducer->AddState();
factor_transducer->SetStart(ss);
factor_transducer->SetFinal(fs, KwsProductWeight::One());
@ -285,7 +260,7 @@ void RemoveLongSilences(int32 max_silence_frames,
// Skip arcs start from the initial state
if (s == ss)
continue;
for (MutableArcIterator<KwsProductFst>
for (MutableArcIterator<KwsProductFst>
aiter(factor_transducer, s); !aiter.Done(); aiter.Next()) {
KwsProductArc arc = aiter.Value();
// Skip arcs end with the final state
@ -324,13 +299,13 @@ static void DifferenceWrapper(const fst::VectorFst<Arc> &fst1,
DifferenceWrapper(fst1_copy, fst2_copy, difference);
Decode(difference, encoder);
} else {
VectorFst<Arc> fst2_copy(fst2);
VectorFst<Arc> fst2_copy(fst2);
RmEpsilon(&fst2_copy); // or Difference will crash.
RemoveWeights(&fst2_copy); // or Difference will crash.
Difference(fst1, fst2_copy, difference);
}
}
void MaybeDoSanityCheck(const KwsLexicographicFst &index_transducer) {
typedef KwsLexicographicFst::Arc::Label Label;
@ -355,7 +330,7 @@ void MaybeDoSanityCheck(const KwsLexicographicFst &index_transducer) {
// into a transducer).
KwsLexicographicFst difference_transducer;
DifferenceWrapper(index_transducer, temp_transducer, &difference_transducer);
ShortestPath(difference_transducer, &temp_transducer);
ShortestPath(difference_transducer, &temp_transducer);
GetLinearSymbolSequence(temp_transducer, &isymbols, &osymbols, &weight);
std::ostringstream os2;
@ -369,7 +344,7 @@ void MaybeDoSanityCheck(const KwsLexicographicFst &index_transducer) {
KALDI_WARN << "Negative second-best cost found " << second_best_cost;
}
}
void MaybeDoSanityCheck(const KwsProductFst &product_transducer) {
if (GetVerboseLevel() < 2) return;
@ -379,114 +354,5 @@ void MaybeDoSanityCheck(const KwsProductFst &product_transducer) {
}
// This function replaces a symbol with epsilon wherever it appears
// (fst must be an acceptor).
template<class Arc>
static void ReplaceSymbolWithEpsilon(typename Arc::Label symbol,
fst::VectorFst<Arc> *fst) {
typedef typename Arc::StateId StateId;
for (StateId s = 0; s < fst->NumStates(); s++) {
for (fst::MutableArcIterator<fst::VectorFst<Arc> > aiter(fst, s);
!aiter.Done(); aiter.Next()) {
Arc arc = aiter.Value();
KALDI_ASSERT(arc.ilabel == arc.olabel);
if (arc.ilabel == symbol) {
arc.ilabel = 0;
arc.olabel = 0;
aiter.SetValue(arc);
}
}
}
}
void DoFactorMerging(KwsProductFst *factor_transducer,
KwsLexicographicFst *index_transducer) {
using namespace fst;
typedef KwsProductFst::Arc::Label Label;
// Encode the transducer first
EncodeMapper<KwsProductArc> encoder(kEncodeLabels, ENCODE);
Encode(factor_transducer, &encoder);
// We want DeterminizeStar to remove epsilon arcs, so turn whatever it encoded
// epsilons as, into actual epsilons.
{
KwsProductArc epsilon_arc(0, 0, KwsProductWeight::One(), 0);
Label epsilon_label = encoder(epsilon_arc).ilabel;
ReplaceSymbolWithEpsilon(epsilon_label, factor_transducer);
}
MaybeDoSanityCheck(*factor_transducer);
// Use DeterminizeStar
KALDI_VLOG(2) << "DoFactorMerging: determinization...";
KwsProductFst dest_transducer;
DeterminizeStar(*factor_transducer, &dest_transducer);
MaybeDoSanityCheck(dest_transducer);
// Commenting the minimization out, as it moves states/arcs in a way we don't
// want in some rare cases. For example, if we have two arcs from starting
// state, which have same words on the input side, but different cluster IDs
// on the output side, it may make the two arcs sharing a common final arc,
// which will cause problem in the factor disambiguation stage (we will not
// be able to add disambiguation symbols for both paths). We do a final step
// optimization anyway so commenting this out shouldn't matter too much.
// KALDI_VLOG(2) << "DoFactorMerging: minimization...";
// Minimize(&dest_transducer);
MaybeDoSanityCheck(dest_transducer);
Decode(&dest_transducer, encoder);
Map(dest_transducer, index_transducer, KwsProductFstToKwsLexicographicFstMapper());
}
void DoFactorDisambiguation(KwsLexicographicFst *index_transducer) {
using namespace fst;
typedef KwsLexicographicArc::StateId StateId;
StateId ns = index_transducer->NumStates();
for (StateId s = 0; s < ns; s++) {
for (MutableArcIterator<KwsLexicographicFst>
aiter(index_transducer, s); !aiter.Done(); aiter.Next()) {
KwsLexicographicArc arc = aiter.Value();
if (index_transducer->Final(arc.nextstate) != KwsLexicographicWeight::Zero())
arc.ilabel = s;
else
arc.olabel = 0;
aiter.SetValue(arc);
}
}
}
void OptimizeFactorTransducer(KwsLexicographicFst *index_transducer,
int32 max_states,
bool allow_partial) {
using namespace fst;
KwsLexicographicFst ifst = *index_transducer;
EncodeMapper<KwsLexicographicArc> encoder(kEncodeLabels, ENCODE);
Encode(&ifst, &encoder);
KALDI_VLOG(2) << "OptimizeFactorTransducer: determinization...";
if (allow_partial) {
DeterminizeStar(ifst, index_transducer, kDelta, NULL, max_states, true);
} else {
try {
DeterminizeStar(ifst, index_transducer, kDelta, NULL, max_states,
false);
} catch(const std::exception &e) {
KALDI_WARN << e.what();
*index_transducer = ifst;
}
}
KALDI_VLOG(2) << "OptimizeFactorTransducer: minimization...";
Minimize(index_transducer);
Decode(index_transducer, encoder);
}
} // end namespace kaldi

Просмотреть файл

@ -51,37 +51,37 @@ class Interval {
// We define a function bool CompareInterval(const Interval &i1, const Interval
// &i2) to compare the Interval defined above. If interval i1 is in front of
// interval i2, then return true; otherwise return false.
bool CompareInterval(const Interval &i1,
const Interval &i2);
bool CompareInterval(const Interval &i1,
const Interval &i2);
// This function clusters the arcs with same word id and overlapping time-spans.
// Examples of clusters:
// 0 1 a a (0.1s ~ 0.5s) and 2 3 a a (0.2s ~ 0.4s) are within the same cluster;
// 0 1 a a (0.1s ~ 0.5s) and 5 6 b b (0.2s ~ 0.4s) are in different clusters;
// 0 1 a a (0.1s ~ 0.5s) and 2 3 a a (0.2s ~ 0.4s) are within the same cluster;
// 0 1 a a (0.1s ~ 0.5s) and 5 6 b b (0.2s ~ 0.4s) are in different clusters;
// 0 1 a a (0.1s ~ 0.5s) and 7 8 a a (0.9s ~ 1.4s) are also in different clusters.
// It puts disambiguating symbols in the olabels, leaving the words on the
// ilabels.
bool ClusterLattice(CompactLattice *clat,
bool ClusterLattice(CompactLattice *clat,
const vector<int32> &state_times);
// This function contains two steps: weight pushing and factor generation. The
// original ShortestDistance() is not very efficient, so we do the weight
// pushing and shortest path manually by computing the alphas and betas. The
// factor generation step expand the lattice to the LXTXT' semiring, with
// additional start state and end state (and corresponding arcs) added.
// additional start state and end state (and corresponding arcs) added.
bool CreateFactorTransducer(const CompactLattice &clat,
const vector<int32> &state_times,
int32 utterance_id,
const vector<int32> &state_times,
int32 utterance_id,
KwsProductFst *factor_transducer);
// This function removes the arcs with long silence. By "long" we mean arcs with
// #frames exceeding the given max_silence_frames. We do this filtering because
// the gap between adjacent words in a keyword must be <= 0.5 second.
// the gap between adjacent words in a keyword must be <= 0.5 second.
// Note that we should not remove the arcs created in the factor generation
// step, so the "search area" is limited to the original arcs before factor
// generation.
void RemoveLongSilences(int32 max_silence_frames,
const vector<int32> &state_times,
// generation.
void RemoveLongSilences(int32 max_silence_frames,
const vector<int32> &state_times,
KwsProductFst *factor_transducer);
// Do the factor merging part: encode input and output, and apply weighted
@ -109,6 +109,40 @@ void MaybeDoSanityCheck(const KwsProductFst &factor_transducer);
void MaybeDoSanityCheck(const KwsLexicographicFst &index_transducer);
// this Mapper class is used in some of the the internals; we have to declare it
// in the header because, for the sake of compilation time, we split up the
// implementation into two .cc files.
class KwsProductFstToKwsLexicographicFstMapper {
public:
typedef KwsProductArc FromArc;
typedef KwsProductWeight FromWeight;
typedef KwsLexicographicArc ToArc;
typedef KwsLexicographicWeight ToWeight;
KwsProductFstToKwsLexicographicFstMapper() {}
inline ToArc operator()(const FromArc &arc) const {
return ToArc(arc.ilabel,
arc.olabel,
(arc.weight == FromWeight::Zero() ?
ToWeight::Zero() :
ToWeight(arc.weight.Value1().Value(),
StdLStdWeight(arc.weight.Value2().Value1().Value(),
arc.weight.Value2().Value2().Value()))),
arc.nextstate);
}
fst::MapFinalAction FinalAction() const { return fst::MAP_NO_SUPERFINAL; }
fst::MapSymbolsAction InputSymbolsAction() const { return fst::MAP_COPY_SYMBOLS; }
fst::MapSymbolsAction OutputSymbolsAction() const { return fst::MAP_COPY_SYMBOLS;}
uint64 Properties(uint64 props) const { return props; }
};
} // namespace kaldi

140
src/kws/kws-functions2.cc Normal file
Просмотреть файл

@ -0,0 +1,140 @@
// kws/kws-functions.cc
// Copyright 2012 Johns Hopkins University (Author: Guoguo Chen)
// See ../../COPYING for clarification regarding multiple authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
// WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
// MERCHANTABLITY OR NON-INFRINGEMENT.
// See the Apache 2 License for the specific language governing permissions and
// limitations under the License.
#include "lat/lattice-functions.h"
#include "kws/kws-functions.h"
#include "fstext/determinize-star.h"
#include "fstext/epsilon-property.h"
// this file implements things in kws-functions.h; it's an overflow from
// kws-functions.cc (we split it up for compilation speed and to avoid
// generating too-large object files on cygwin).
namespace kaldi {
// This function replaces a symbol with epsilon wherever it appears
// (fst must be an acceptor).
template<class Arc>
static void ReplaceSymbolWithEpsilon(typename Arc::Label symbol,
fst::VectorFst<Arc> *fst) {
typedef typename Arc::StateId StateId;
for (StateId s = 0; s < fst->NumStates(); s++) {
for (fst::MutableArcIterator<fst::VectorFst<Arc> > aiter(fst, s);
!aiter.Done(); aiter.Next()) {
Arc arc = aiter.Value();
KALDI_ASSERT(arc.ilabel == arc.olabel);
if (arc.ilabel == symbol) {
arc.ilabel = 0;
arc.olabel = 0;
aiter.SetValue(arc);
}
}
}
}
void DoFactorMerging(KwsProductFst *factor_transducer,
KwsLexicographicFst *index_transducer) {
using namespace fst;
typedef KwsProductFst::Arc::Label Label;
// Encode the transducer first
EncodeMapper<KwsProductArc> encoder(kEncodeLabels, ENCODE);
Encode(factor_transducer, &encoder);
// We want DeterminizeStar to remove epsilon arcs, so turn whatever it encoded
// epsilons as, into actual epsilons.
{
KwsProductArc epsilon_arc(0, 0, KwsProductWeight::One(), 0);
Label epsilon_label = encoder(epsilon_arc).ilabel;
ReplaceSymbolWithEpsilon(epsilon_label, factor_transducer);
}
MaybeDoSanityCheck(*factor_transducer);
// Use DeterminizeStar
KALDI_VLOG(2) << "DoFactorMerging: determinization...";
KwsProductFst dest_transducer;
DeterminizeStar(*factor_transducer, &dest_transducer);
MaybeDoSanityCheck(dest_transducer);
// Commenting the minimization out, as it moves states/arcs in a way we don't
// want in some rare cases. For example, if we have two arcs from starting
// state, which have same words on the input side, but different cluster IDs
// on the output side, it may make the two arcs sharing a common final arc,
// which will cause problem in the factor disambiguation stage (we will not
// be able to add disambiguation symbols for both paths). We do a final step
// optimization anyway so commenting this out shouldn't matter too much.
// KALDI_VLOG(2) << "DoFactorMerging: minimization...";
// Minimize(&dest_transducer);
MaybeDoSanityCheck(dest_transducer);
Decode(&dest_transducer, encoder);
Map(dest_transducer, index_transducer, KwsProductFstToKwsLexicographicFstMapper());
}
void DoFactorDisambiguation(KwsLexicographicFst *index_transducer) {
using namespace fst;
typedef KwsLexicographicArc::StateId StateId;
StateId ns = index_transducer->NumStates();
for (StateId s = 0; s < ns; s++) {
for (MutableArcIterator<KwsLexicographicFst>
aiter(index_transducer, s); !aiter.Done(); aiter.Next()) {
KwsLexicographicArc arc = aiter.Value();
if (index_transducer->Final(arc.nextstate) != KwsLexicographicWeight::Zero())
arc.ilabel = s;
else
arc.olabel = 0;
aiter.SetValue(arc);
}
}
}
void OptimizeFactorTransducer(KwsLexicographicFst *index_transducer,
int32 max_states,
bool allow_partial) {
using namespace fst;
KwsLexicographicFst ifst = *index_transducer;
EncodeMapper<KwsLexicographicArc> encoder(kEncodeLabels, ENCODE);
Encode(&ifst, &encoder);
KALDI_VLOG(2) << "OptimizeFactorTransducer: determinization...";
if (allow_partial) {
DeterminizeStar(ifst, index_transducer, kDelta, NULL, max_states, true);
} else {
try {
DeterminizeStar(ifst, index_transducer, kDelta, NULL, max_states,
false);
} catch(const std::exception &e) {
KALDI_WARN << e.what();
*index_transducer = ifst;
}
}
KALDI_VLOG(2) << "OptimizeFactorTransducer: minimization...";
Minimize(index_transducer);
Decode(index_transducer, encoder);
}
} // end namespace kaldi

Просмотреть файл

@ -7,11 +7,11 @@ endif
DOUBLE_PRECISION = 0
CXXFLAGS = -msse -msse2 -Wall -I.. -DKALDI_DOUBLEPRECISION=$(DOUBLE_PRECISION) \
-DHAVE_POSIX_MEMALIGN -DHAVE_CLAPACK -I ../../tools/CLAPACK/ \
-Wno-sign-compare -Winit-self \
-Wno-sign-compare -Wno-unused-local-typedefs -Winit-self \
-I ../../tools/CLAPACK/ \
-I $(FSTROOT)/include \
$(EXTRA_CXXFLAGS) \
-g # -O0 -DKALDI_PARANOID
-g # -O0 -DKALDI_PARANOID
ifeq ($(KALDI_FLAVOR), dynamic)
CXXFLAGS += -fPIC

Просмотреть файл

@ -955,22 +955,22 @@ void AddInputToGraph(const ComputationRequest &request,
// This function outputs to dependencies_subset[c], for each cindex_id c,
// the subset of elements d of graph.dependencies[c] such that
// cindex_id_to_phase[d] == cindex_id_to_phase[d].
// cindex_id_to_epoch[d] == cindex_id_to_epoch[c].
static void ComputeDependenciesSubset(
const ComputationGraph &graph,
const std::vector<int32> &cindex_id_to_phase,
const std::vector<int32> &cindex_id_to_epoch,
std::vector<std::vector<int32> > *dependencies_subset) {
int32 num_cindex_ids = graph.cindexes.size();
KALDI_ASSERT(cindex_id_to_phase.size() == num_cindex_ids);
KALDI_ASSERT(cindex_id_to_epoch.size() == num_cindex_ids);
dependencies_subset->resize(num_cindex_ids);
for (int32 cindex_id = 0; cindex_id < num_cindex_ids; cindex_id++) {
int32 phase_index = cindex_id_to_phase[cindex_id];
int32 phase_index = cindex_id_to_epoch[cindex_id];
const std::vector<int32> &dependencies = graph.dependencies[cindex_id];
std::vector<int32> &dep_subset = (*dependencies_subset)[cindex_id];
int32 num_dep = dependencies.size();
for (int32 i = 0; i < num_dep; i++) {
int32 d = dependencies[i];
if (cindex_id_to_phase[d] == phase_index)
if (cindex_id_to_epoch[d] == phase_index)
dep_subset.push_back(d);
}
}