diff --git a/BrainScript/BrainScriptEvaluator.cpp b/BrainScript/BrainScriptEvaluator.cpp index d021ae9bc..0f4b8eb6f 100644 --- a/BrainScript/BrainScriptEvaluator.cpp +++ b/BrainScript/BrainScriptEvaluator.cpp @@ -616,7 +616,7 @@ namespace Microsoft { namespace MSR { namespace BS { else if (what == L"Length") { if (arg.Is()) - us = (double)((wstring)arg).size(); + us = (double)((wstring&)arg).size(); else // otherwise expect an array { let arr = (ConfigArray)arg; @@ -730,7 +730,7 @@ namespace Microsoft { namespace MSR { namespace BS { // ----------------------------------------------------------------------- // internal types (such as string functions) -#define DefineRuntimeType(T) { L#T, MakeRuntimeTypeConstructor() } +#define DefineRuntimeType(T) { L ## #T, MakeRuntimeTypeConstructor() } template static ConfigurableRuntimeType MakeRuntimeTypeConstructor() { diff --git a/BrainScript/BrainScriptEvaluator.h b/BrainScript/BrainScriptEvaluator.h index 972f53c40..92ccdf2cf 100644 --- a/BrainScript/BrainScriptEvaluator.h +++ b/BrainScript/BrainScriptEvaluator.h @@ -113,6 +113,8 @@ namespace Microsoft { namespace MSR { namespace BS { template operator shared_ptr() const { return AsPtr(); } // access as a (const & to) value --use this for primitive types (also works to get a const wstring & from a String) template operator T() const { return AsRef(); } + // Linux gcc barfs on this ^^ for 'us = (double)((wstring)arg).size();' due to some ambiguity error (while it works fine with Visual Studio). + // If you encounter this, instead say 'us = (double)((wstring&)arg).size();' with a & operator double() const { return AsRef(); } operator float() const { return (float) AsRef(); } operator bool() const { return AsRef(); } diff --git a/BrainScript/BrainScriptParser.cpp b/BrainScript/BrainScriptParser.cpp index 7f8983167..b07f647f3 100644 --- a/BrainScript/BrainScriptParser.cpp +++ b/BrainScript/BrainScriptParser.cpp @@ -109,8 +109,8 @@ struct Issue if (!locations.empty()) // (be resilient to some throwers not having a TextrLocation; to be avoided) { let & firstLoc = issues.front().location; - fprintf(stderr, "\n%ls while %ls line %d char %d of %ls\n", errorKind, kind, firstLoc.lineNo + 1/*report 1-based*/, firstLoc.charPos + 1, firstLoc.GetSourceFile().path.c_str()); - fprintf(stderr, "see location marked ^ and parent contexts marked 0..9, a..z, A..Z:\n\n", errorKind, kind); + fprintf(stderr, "\n%ls while %ls line %d char %d of %ls\n", errorKind, kind, (int)firstLoc.lineNo + 1/*report 1-based*/, (int)firstLoc.charPos + 1, firstLoc.GetSourceFile().path.c_str()); + fprintf(stderr, "see location marked ^ and parent contexts marked 0..9, a..z, A..Z:\n\n"); for (auto i = issues.rbegin(); i != issues.rend(); i++) { let & issue = *i; @@ -444,7 +444,7 @@ public: // diagnostics helper: print the content void Expression::Dump(int indent) const { - fprintf(stderr, "%*s", indent, "", op.c_str()); + fprintf(stderr, "%*s", indent, ""); if (op == L"s") fprintf(stderr, "'%ls' ", s.c_str()); else if (op == L"d") fprintf(stderr, "%.f ", d); else if (op == L"b") fprintf(stderr, "%s ", b ? "true" : "false"); diff --git a/BrainScript/BrainScriptTest.cpp b/BrainScript/BrainScriptTest.cpp index bdc49e480..9ea6e4010 100644 --- a/BrainScript/BrainScriptTest.cpp +++ b/BrainScript/BrainScriptTest.cpp @@ -67,7 +67,7 @@ namespace Microsoft { namespace MSR { namespace BS { try { // collecting all sorts of test cases here - wchar_t * parserTests[] = + const wchar_t * parserTests[] = { L"do = Parameter(13,42) * Input(42) + Parameter(13,1)" , @@ -198,7 +198,7 @@ namespace Microsoft { namespace MSR { namespace BS { bool oneOnly = first > 0; for (size_t i = first; parserTests[i]; i++) { - fprintf(stderr, "\n### Test %d ###\n\n", i), fflush(stderr); + fprintf(stderr, "\n### Test %d ###\n\n", (int)i), fflush(stderr); let parserTest = parserTests[i]; let expr = ParseConfigString(standardFunctions + computationNodes + commonMacros + parserTest); //expr->Dump(); diff --git a/CNTK.sln b/CNTK.sln index 5467b27a4..ca83fada4 100644 --- a/CNTK.sln +++ b/CNTK.sln @@ -84,9 +84,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibSVMBinaryReader", "DataR EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux build files", "Linux build files", "{3ED0465D-23E7-4855-9694-F788717B6533}" ProjectSection(SolutionItems) = preProject + configure = configure Makefile = Makefile - Makefile_kaldi.cpu = Makefile_kaldi.cpu - Makefile_kaldi.gpu = Makefile_kaldi.gpu README = README EndProjectSection EndProject diff --git a/MachineLearning/CNTK/ComputationNetwork.h b/MachineLearning/CNTK/ComputationNetwork.h index 0f02cd094..2a202532b 100644 --- a/MachineLearning/CNTK/ComputationNetwork.h +++ b/MachineLearning/CNTK/ComputationNetwork.h @@ -2880,7 +2880,7 @@ protected: // Copy constructor, should never be called. #pragma warning (push) #pragma warning (disable: 4702) // this function is flagged but unclear why - ComputationNetwork(const ComputationNetwork& /*deepCopyFrom*/) + ComputationNetwork(const ComputationNetwork& /*deepCopyFrom*/) { // TODO: can we just define it as private without implementation? LogicError("'ComputationNetwork(const ComputationNetwork& deepCopyFrom)' should never be called."); diff --git a/MachineLearning/CNTK/ExperimentalNetworkBuilder.cpp b/MachineLearning/CNTK/ExperimentalNetworkBuilder.cpp index 27db1bda6..f6a9d9bbe 100644 --- a/MachineLearning/CNTK/ExperimentalNetworkBuilder.cpp +++ b/MachineLearning/CNTK/ExperimentalNetworkBuilder.cpp @@ -76,10 +76,10 @@ namespace Microsoft { namespace MSR { namespace BS { L"ClassificationError = ErrorPrediction \n" L"Delay = PastValue \n" // TODO: should it allow negative offsets and an if test here? // standard nodes. We use macros to define these strings. -#define UnaryStandardNode(Op,a) L#Op L"(" L#a L", tag='') = new ComputationNode [ operation = '" L#Op L"' ; inputs = " L#a L" /*plus the function args*/ ]\n" -#define BinaryStandardNode(Op,a,b) L#Op L"(" L#a L", " L#b L", tag='') = new ComputationNode [ operation = '" L#Op L"' ; inputs = (" L#a L" : " L#b L") /*plus the function args*/ ]\n" -#define TernaryStandardNode(Op,a,b,c) L#Op L"(" L#a L", " L#b L", " L#c L", tag='') = new ComputationNode [ operation = '" L#Op L"' ; inputs = (" L#a L" : " L#b L" : " L#c L") /*plus the function args*/ ]\n" -#define QuaternaryStandardNode(Op,a,b,c,d) L#Op L"(" L#a L", " L#b L", " L#c L", " L#d L", tag='') = new ComputationNode [ operation = '" L#Op L"' ; inputs = (" L#a L" : " L#b L" : " L#c L" : " L#d L") /*plus the function args*/ ]\n" +#define UnaryStandardNode(Op,a) L ## #Op L"(" L ## #a L", tag='') = new ComputationNode [ operation = '" L ## #Op L"' ; inputs = " L ## #a L" /*plus the function args*/ ]\n" +#define BinaryStandardNode(Op,a,b) L ## #Op L"(" L ## #a L", " L ## #b L", tag='') = new ComputationNode [ operation = '" L ## #Op L"' ; inputs = (" L ## #a L" : " L ## #b L") /*plus the function args*/ ]\n" +#define TernaryStandardNode(Op,a,b,c) L ## #Op L"(" L ## #a L", " L ## #b L", " L ## #c L", tag='') = new ComputationNode [ operation = '" L ## #Op L"' ; inputs = (" L ## #a L" : " L ## #b L" : " L ## #c L") /*plus the function args*/ ]\n" +#define QuaternaryStandardNode(Op,a,b,c,d) L ## #Op L"(" L ## #a L", " L ## #b L", " L ## #c L", " L ## #d L", tag='') = new ComputationNode [ operation = '" L ## #Op L"' ; inputs = (" L ## #a L" : " L ## #b L" : " L ## #c L" : " L ## #d L") /*plus the function args*/ ]\n" TernaryStandardNode(CRF, labelVectorSequence, positionDependenScoreVectorSequence, transitionScores) // TODO: better names QuaternaryStandardNode(ClassBasedCrossEntropyWithSoftmax, labelClassDescriptorVectorSequence, mainInputInfo, mainWeight, classLogProbsBeforeSoftmax) // BUGBUG: the commented-out ones are not mentioned in the CNTK book, nor are their parameters documented in the source code @@ -829,8 +829,8 @@ namespace Microsoft { namespace MSR { namespace BS { return rtInfo; } - //#define DefineRuntimeType(T) { L#T, MakeRuntimeTypeConstructors() } } -#define DefineRuntimeTypeDualPrecision(T) { L#T, MakeRuntimeTypeConstructorDualPrecision,T>() } + //#define DefineRuntimeType(T) { L ## #T, MakeRuntimeTypeConstructors() } } +#define DefineRuntimeTypeDualPrecision(T) { L ## #T, MakeRuntimeTypeConstructorDualPrecision,T>() } // get information about configurable runtime types // This returns a ConfigurableRuntimeType structure which primarily contains a lambda to construct a runtime object from a ConfigRecord ('new' expression). @@ -865,8 +865,8 @@ namespace Microsoft { namespace MSR { namespace CNTK { // helper that returns 'float' or 'double' depending on ElemType template static const wchar_t * ElemTypeName(); - template<> static const wchar_t * ElemTypeName() { return L"float"; } - template<> static const wchar_t * ElemTypeName() { return L"double"; } + template<> /*static*/ const wchar_t * ElemTypeName() { return L"float"; } + template<> /*static*/ const wchar_t * ElemTypeName() { return L"double"; } // build a ComputationNetwork from BrainScript source code template @@ -878,7 +878,7 @@ namespace Microsoft { namespace MSR { namespace CNTK { // We prepend a few standard definitions, and also definition of deviceId and precision, which all objects will pull out again when they are being constructed. // BUGBUG: We are not getting TextLocations right in this way! Do we need to inject location markers into the source? let expr = BS::ParseConfigString(BS::standardFunctions + BS::computationNodes + BS::commonMacros - + wstrprintf(L"deviceId = %d ; precision = '%s' ; network = new ComputationNetwork ", (int)m_deviceId, ElemTypeName()) // TODO: check if typeid needs postprocessing + + msra::strfun::wstrprintf(L"deviceId = %d ; precision = '%s' ; network = new ComputationNetwork ", (int)m_deviceId, ElemTypeName()) // TODO: check if typeid needs postprocessing + m_sourceCode); // source code has the form [ ... ] // evaluate the parse tree--specifically the top-level field 'network'--which will create the network let object = EvaluateField(expr, L"network"); // this comes back as a BS::Object diff --git a/MachineLearning/CNTK/IComputationNetBuilder.h b/MachineLearning/CNTK/IComputationNetBuilder.h index ab52a523e..9f9505994 100644 --- a/MachineLearning/CNTK/IComputationNetBuilder.h +++ b/MachineLearning/CNTK/IComputationNetBuilder.h @@ -8,19 +8,16 @@ #include "ComputationNetwork.h" #include -namespace Microsoft { - namespace MSR { - namespace CNTK { +namespace Microsoft { namespace MSR { namespace CNTK { - template - class IComputationNetBuilder //Abstract Class that cannot be instantiated - { - public: - virtual ComputationNetwork* LoadNetworkFromFile(const std::wstring& modelFileName, bool forceLoad = true, - bool bAllowNoCriterion = false, ComputationNetwork* = nullptr) = 0; - virtual ComputationNetwork* BuildNetworkFromDescription(ComputationNetwork* = nullptr) = 0; - virtual ~IComputationNetBuilder() {}; - }; - } - } -} \ No newline at end of file + template + class IComputationNetBuilder //Abstract Class that cannot be instantiated + { + public: + virtual ComputationNetwork* LoadNetworkFromFile(const std::wstring& modelFileName, bool forceLoad = true, + bool bAllowNoCriterion = false, ComputationNetwork* = nullptr) = 0; + virtual ComputationNetwork* BuildNetworkFromDescription(ComputationNetwork* = nullptr) = 0; + virtual ~IComputationNetBuilder() {}; + }; + +}}} diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..a8306b1ee --- /dev/null +++ b/Makefile @@ -0,0 +1,417 @@ +# Makefile for a Linux/GCC build of CNTK +# +# The Linux and Windows versions are not different branches, but rather build off the same +# source files, using different makefiles. This current makefile has the purpose of enabling +# work to make all sources compile with GCC, and also to check for GCC-compat regressions due to +# modifications which are currently done under Windows. +# +# This makefile will be extended/completed as we go. +# +# To use this Makefile, create a directory to build in and make a Config.make in the directory +# that provides +# ACML_PATH= path to ACML library installation +# only needed if MATHLIB=acml +# MKL_PATH= path to MKL library installation +# only needed if MATHLIB=mkl +# GDK_PATH= path to cuda gdk installation, so $(GDK_PATH)/include/nvidia/gdk/nvml.h exists +# defaults to /usr +# BUILDTYPE= One of release or debug +# defaults to release +# MATHLIB= One of acml or mkl +# defaults to acml +# CUDA_PATH= Path to CUDA +# If not specified, GPU will not be enabled +# KALDI_PATH= Path to Kaldi +# If not specified, Kaldi plugins will not be built + +ifndef BUILD_TOP +BUILD_TOP=. +endif + +ifneq ("$(wildcard $(BUILD_TOP)/Config.make)","") + include $(BUILD_TOP)/Config.make +else + $(error Cannot fine $(BUILD_TOP)/Config.make. Please see the README file for configuration instructions.) +endif + +ifndef BUILDTYPE +$(info Defaulting BUILDTYPE=release) +BUILDTYPE=release +endif + +ifndef MATHLIB +$(info DEFAULTING MATHLIB=acml) +MATHLIB = acml +endif + +#### Configure based on options above + +# The mpic++ wrapper only adds MPI specific flags to the g++ command line. +# The actual compiler/linker flags added can be viewed by running 'mpic++ --showme:compile' and 'mpic++ --showme:link' +CXX = mpic++ + +INCLUDEPATH:= Common/Include Math/Math MachineLearning/CNTK BrainScript +CPPFLAGS:= -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 -D__USE_XOPEN2K +CXXFLAGS:= -msse3 -std=c++0x -std=c++11 -fopenmp -fpermissive -fPIC +LIBPATH:= +LIBS:= +LDFLAGS:= + +SEPARATOR = "=-----------------------------------------------------------=" +ALL:= +SRC:= + +# Make sure all is the first (i.e. default) target, but we can't actually define it +# this early in the file, so let buildall do the work. +all : buildall + +# Set up nvcc target architectures (will generate code to support them all, i.e. fat-binary) +GENCODE_SM20 := -gencode arch=compute_20,code=\"sm_20,compute_20\" +GENCODE_SM30 := -gencode arch=compute_30,code=\"sm_30,compute_30\" +GENCODE_SM35 := -gencode arch=compute_35,code=\"sm_35,compute_35\" +GENCODE_FLAGS := $(GENCODE_SM20) $(GENCODE_SM30) $(GENCODE_SM35) + +# Set up basic nvcc options and add CUDA targets from above +CUFLAGS = -std=c++11 -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 -D__USE_XOPEN2K -m 64 $(GENCODE_FLAGS) + +ifdef CUDA_PATH + ifndef GDK_PATH + $(info defaulting GDK_PATH to /usr) + GDK_PATH=/usr +endif + + DEVICE = gpu + + NVCC = $(CUDA_PATH)/bin/nvcc + + # This is a suggested/default location for NVML + INCLUDEPATH+=$(GDK_PATH)/include/nvidia/gdk + NVMLPATH=$(GDK_PATH)/src/gdk/nvml/lib + +# Set up CUDA includes and libraries + INCLUDEPATH += $(CUDA_PATH)/include + LIBPATH += $(CUDA_PATH)/lib64 + LIBS += -lcublas -lcudart -lcuda -lcurand -lcusparse -lnvidia-ml + +else + DEVICE = cpu + + CPPFLAGS +=-DCPUONLY +endif + +ifeq ("$(MATHLIB)","acml") + INCLUDEPATH += $(ACML_PATH)/include + LIBPATH += $(ACML_PATH)/lib + LIBS += -lacml -lm -lpthread + CPPFLAGS += -DUSE_ACML +endif + +ifeq ("$(MATHLIB)","mkl") + INCLUDEPATH += $(MKL_PATH)/mkl/include + LIBPATH += $(MKL_PATH)/compiler/lib/intel64 $(MKL_PATH)/mkl/lib/intel64 $(MKL_PATH)/compiler/lib/mic $(MKL_PATH)/mkl/lib/mic + LIBS += -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -lm -liomp5 -lpthread + CPPFLAGS += -DUSE_MKL +endif + + +ifdef KALDI_PATH + ########## Copy includes and defines from $(KALDI_PATH)/src/kaldi.mk ########## + FSTROOT = $(KALDI_PATH)/tools/openfst + ATLASINC = $(KALDI_PATH)/tools/ATLAS/include + + INCLUDEPATH += $(KALDI_PATH)/src $(ATLASINC) $(FSTROOT)/include + CPPFLAGS+= -DKALDI_DOUBLEPRECISION=0 -DHAVE_POSIX_MEMALIGN -DHAVE_EXECINFO_H=1 -DHAVE_CXXABI_H -DHAVE_ATLAS -DHAVE_OPENFST_GE_10400 + + KALDI_LIBPATH += $(KALDI_PATH)/src/lib + KALDI_LIBS += -lkaldi-util -lkaldi-matrix -lkaldi-base -lkaldi-hmm -lkaldi-cudamatrix -lkaldi-nnet -lkaldi-lat +endif + +ifeq ("$(BUILDTYPE)","debug") + CXXFLAGS += -g + CUFLAGS += -O0 -G -lineinfo +endif + +ifeq ("$(BUILDTYPE)","release") + CXXFLAGS += -O4 + CUFLAGS += -O3 -use_fast_math -lineinfo +endif + +####### + +OBJDIR:= $(BUILD_TOP)/.build +BINDIR:= $(BUILD_TOP)/bin +LIBDIR:= $(BUILD_TOP)/lib + +ORIGINLIBDIR:='$$ORIGIN/../lib' +ORIGINDIR:='$$ORIGIN' + +CNTKMATH:=cntkmath + +######################################## +# Math library +######################################## + +# Define all sources that need to be built +COMMON_SRC =\ + Common/BestGpu.cpp \ + Common/ConfigFile.cpp \ + Common/DataReader.cpp \ + Common/DataWriter.cpp \ + Common/Eval.cpp \ + Common/File.cpp \ + Common/TimerUtility.cpp \ + Common/fileutil.cpp \ + +MATH_SRC =\ + Math/Math/CPUMatrix.cpp \ + Math/Math/CPUSparseMatrix.cpp \ + Math/Math/MatrixQuantizer.cpp \ + Math/Math/MatrixQuantizerCPU.cpp \ + Math/Math/QuantizedMatrix.cpp \ + Math/Math/Matrix.cpp \ + +ifdef CUDA_PATH +MATH_SRC +=\ + Math/Math/GPUMatrix.cu \ + Math/Math/GPUMatrixCUDAKernels.cu \ + Math/Math/GPUSparseMatrix.cu \ + Math/Math/GPUWatcher.cu \ + Math/Math/CUDAPageLockedMemAllocator.cpp \ + Math/Math/MatrixQuantizerGPU.cu \ + +else +MATH_SRC +=\ + Math/Math/NoGPU.cpp + +endif + +MATH_SRC+=$(COMMON_SRC) + +MATH_OBJ := $(patsubst %.cu, $(OBJDIR)/%.o, $(patsubst %.cpp, $(OBJDIR)/%.o, $(MATH_SRC))) + +CNTKMATH_LIB:= $(LIBDIR)/lib$(CNTKMATH).so +ALL += $(CNTKMATH_LIB) +SRC+=$(MATH_SRC) + +RPATH=-Wl,-rpath, + +$(CNTKMATH_LIB): $(MATH_OBJ) + @echo $(SEPARATOR) + @echo creating $@ for $(ARCH) with build type $(BUILDTYPE) + @mkdir -p $(dir $@) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBPATH) $(NVMLPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -fopenmp + +######################################## +# BinaryReader plugin +######################################## + +BINARYREADER_SRC =\ + DataReader/BinaryReader/BinaryFile.cpp \ + DataReader/BinaryReader/BinaryReader.cpp \ + DataReader/BinaryReader/BinaryWriter.cpp \ + +BINARYREADER_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(BINARYREADER_SRC)) + +BINARY_READER:= $(LIBDIR)/BinaryReader.so + +#ALL += $(BINARY_READER) +#SRC+=$(BINARYREADER_SRC) + +$(BINARY_READER): $(BINARYREADER_OBJ) | $(CNTKMATH_LIB) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) + +######################################## +# HTKMLFReader plugin +######################################## + +HTKMLFREADER_SRC =\ + DataReader/HTKMLFReader_linux/DataReader.cpp \ + DataReader/HTKMLFReader_linux/DataWriter.cpp \ + DataReader/HTKMLFReader_linux/HTKMLFReader.cpp \ + DataReader/HTKMLFReader_linux/HTKMLFWriter.cpp \ + +HTKMLREADER_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(HTKMLFREADER_SRC)) + +HTKMLREADER:=$(LIBDIR)/HTKMLFReader.so +ALL+=$(HTKMLREADER) +SRC+=$(HTKMLREADER_SRC) + +$(LIBDIR)/HTKMLFReader.so: $(HTKMLREADER_OBJ) | $(CNTKMATH_LIB) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) + +######################################## +# LMSequenceReader plugin +######################################## + +LMSEQUENCEREADER_SRC =\ + DataReader/LMSequenceReader/Exports.cpp \ + DataReader/LMSequenceReader/SequenceParser.cpp \ + DataReader/LMSequenceReader/SequenceReader.cpp \ + +LMSEQUENCEREADER_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(LMSEQUENCEREADER_SRC)) + +LMSEQUENCEREADER:= $(LIBDIR)/LMSequenceReader.so +ALL+=$(LMSEQUENCEREADER) +SRC+=$(LMSEQUENCEREADER_SRC) + +$(LMSEQUENCEREADER): $(LMSEQUENCEREADER_OBJ) | $(CNTKMATH_LIB) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) + +######################################## +# LUSequenceReader plugin +######################################## + +LUSEQUENCEREADER_SRC =\ + DataReader/LUSequenceReader/Exports.cpp \ + DataReader/LUSequenceReader/LUSequenceParser.cpp \ + DataReader/LUSequenceReader/LUSequenceReader.cpp \ + +LUSEQUENCEREADER_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(LUSEQUENCEREADER_SRC)) + +LUSEQUENCEREADER:=$(LIBDIR)/LUSequenceReader.so +ALL+=$(LUSEQUENCEREADER) +SRC+=$(LUSEQUENCEREADER_SRC) + +$(LUSEQUENCEREADER): $(LUSEQUENCEREADER_OBJ) | $(CNTKMATH_LIB) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) + +######################################## +# UCIFastReader plugin +######################################## + +UCIFASTREADER_SRC =\ + DataReader/UCIFastReader/Exports.cpp \ + DataReader/UCIFastReader/UCIFastReader.cpp \ + DataReader/UCIFastReader/UCIParser.cpp \ + +UCIFASTREADER_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(UCIFASTREADER_SRC)) + +UCIFASTREADER:=$(LIBDIR)/UCIFastReader.so +ALL += $(UCIFASTREADER) +SRC+=$(UCIFASTREADER_SRC) + +$(UCIFASTREADER): $(UCIFASTREADER_OBJ) | $(CNTKMATH_LIB) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) + +######################################## +# Kaldi plugins +######################################## + +ifdef KALDI_PATH +KALDIREADER_SRC = \ + DataReader/KaldiReader/DataReader.cpp \ + DataReader/KaldiReader/DataWriter.cpp \ + DataReader/KaldiReader/HTKMLFReader.cpp \ + DataReader/KaldiReader/HTKMLFWriter.cpp \ + +KALDIREADER_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(KALDIREADER_SRC)) + +KALDIREADER:=$(LIBDIR)/KaldiReader.so +ALL+=$(KALDIREADER) +SRC+=$(KALDIREADER_SRC) + +$(KALDIREADER): $(KALDIREADER_OBJ) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(KALDI_LIBPATH) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(KALDI_LIBPATH) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) $(KALDI_LIBS) + +KALDIWRITER:=$(LIBDIR)/KaldiWriter.so +ALL+=$(KALDIWRITER) + +$(KALDIWRITER): $(KALDIREADER_OBJ) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) + + +KALDI2READER_SRC = \ + DataReader/Kaldi2Reader/DataReader.cpp \ + DataReader/Kaldi2Reader/DataWriter.cpp \ + DataReader/Kaldi2Reader/HTKMLFReader.cpp \ + DataReader/Kaldi2Reader/HTKMLFWriter.cpp \ + DataReader/Kaldi2Reader/KaldiSequenceTrainingDerivative.cpp \ + DataReader/Kaldi2Reader/UtteranceDerivativeBuffer.cpp \ + +KALDI2READER_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(KALDI2READER_SRC)) + +KALDI2READER:=$(LIBDIR)/Kaldi2Reader.so +ALL+=$(KALDI2READER) +SRC+=$(KALDI2READER_SRC) + +$(KALDI2READER): $(KALDI2READER_OBJ) + @echo $(SEPARATOR) + $(CXX) $(LDFLAGS) -shared $(patsubst %,-L%, $(LIBDIR) $(KALDI_LIBPATH) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINDIR) $(KALDI_LIBPATH) $(LIBPATH)) -o $@ $^ -l$(CNTKMATH) $(KALDI_LIBS) + +endif + +######################################## +# cntk +######################################## + +CNTK_SRC =\ + MachineLearning/CNTK/CNTK.cpp \ + MachineLearning/CNTK/ComputationNode.cpp \ + MachineLearning/CNTK/ModelEditLanguage.cpp \ + MachineLearning/CNTK/NetworkDescriptionLanguage.cpp \ + MachineLearning/CNTK/Profiler.cpp \ + MachineLearning/CNTK/SimpleNetworkBuilder.cpp \ + MachineLearning/CNTK/tests.cpp \ + MachineLearning/CNTKEval/CNTKEval.cpp \ + BrainScript/BrainScriptEvaluator.cpp \ + BrainScript/BrainScriptParser.cpp \ + BrainScript/BrainScriptTest.cpp \ + MachineLearning/CNTK/ExperimentalNetworkBuilder.cpp \ + +CNTK_OBJ := $(patsubst %.cpp, $(OBJDIR)/%.o, $(CNTK_SRC)) + +CNTK:=$(BINDIR)/cntk +ALL+=$(CNTK) + +$(CNTK): $(CNTK_OBJ) | $(CNTKMATH_LIB) + @echo $(SEPARATOR) + @mkdir -p $(dir $@) + @echo building output for $(ARCH) with build type $(BUILDTYPE) + $(CXX) $(LDFLAGS) $(patsubst %,-L%, $(LIBDIR) $(LIBPATH)) $(patsubst %,$(RPATH)%, $(ORIGINLIBDIR) $(LIBPATH)) -o $@ $^ $(LIBS) -l$(CNTKMATH) -fopenmp + +######################################## +# General compile and dependency rules +######################################## + +VPATH := $(sort $(dir $(SRC))) + +# Define object files +OBJ := $(patsubst %.cu, $(OBJDIR)/%.o, $(patsubst %.cpp, $(OBJDIR)/%.o, $(SRC))) + +# C++ include dependencies generated by -MF compiler option +DEP := $(patsubst %.o, %.d, $(OBJ)) + +# Include all C++ dependencies, like header files, to ensure that a change in those +# will result in the rebuild. +-include ${DEP} + +$(OBJDIR)/%.o : %.cu Makefile + @echo $(SEPARATOR) + @echo creating $@ for $(ARCH) with build type $(BUILDTYPE) + @mkdir -p $(dir $@) + $(NVCC) -c $< -o $@ $(CUFLAGS) $(INCLUDEPATH:%=-I%) -Xcompiler -fPIC + +$(OBJDIR)/%.o : %.cpp Makefile + @echo $(SEPARATOR) + @echo creating $@ for $(ARCH) with build type $(BUILDTYPE) + @mkdir -p $(dir $@) + $(CXX) -c $< -o $@ $(CPPFLAGS) $(CXXFLAGS) $(INCLUDEPATH:%=-I%) -MD -MP -MF ${@:.o=.d} + +.PHONY: clean buildall all + +clean: + @echo $(SEPARATOR) + @rm -rf $(OBJDIR) + @rm -rf $(ALL) + @echo finished cleaning up the project + +buildall : $(ALL) + @echo $(SEPARATOR) + @echo finished building for $(ARCH) with build type $(BUILDTYPE)