Permalink
Browse files

Stand alone trainer and predictor for Bonsai

  • Loading branch information...
Aditya Kusupati
Aditya Kusupati committed Nov 15, 2017
1 parent 6d20b0a commit 89da7e92c1f8c3ecc66c580ef4d5df061719549d
View
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include "Bonsai.h"
using namespace EdgeML;
using namespace EdgeML::Bonsai;
int main(int argc, char **argv)
{
#ifdef LINUX
trapfpe();
struct sigaction sa;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = fpehandler;
sigaction (SIGFPE, &sa, NULL);
#endif
assert (sizeof(MKL_INT) == sizeof(Eigen::Index));
BonsaiPredictor predictor(argc, (const char**) argv); // use the constructor predictor(modelBytes, model, false) for loading a sparse model.
return 0;
}
View
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include "Bonsai.h"
using namespace EdgeML;
using namespace EdgeML::Bonsai;
int main(int argc, char **argv)
{
#ifdef LINUX
trapfpe();
struct sigaction sa;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = fpehandler;
sigaction (SIGFPE, &sa, NULL);
#endif
assert (sizeof(MKL_INT) == sizeof(Eigen::Index));
std::string dataDir;
std::string currResultsPath;
BonsaiTrainer trainer(DataIngestType::FileIngest, argc, (const char**) argv,
dataDir, currResultsPath);
auto modelBytes = trainer.getModelSize(); // This can be changed to getSparseModelSize() if you need to export sparse model
auto model = new char[modelBytes];
auto meanVarBytes = trainer.getMeanVarSize();
auto meanVar = new char[meanVarBytes];
trainer.exportModel(modelBytes, model, currResultsPath); // use exportSparseModel(...) if you need sparse model
trainer.exportMeanVar(meanVarBytes, meanVar, currResultsPath);
trainer.dumpModelMeanVar(currResultsPath);
delete[] model, meanVar;
return 0;
}
View
@@ -11,7 +11,7 @@ BONSAI_INCLUDES=$(SOURCE_DIR)/Bonsai
IFLAGS=-I eigen/ -I$(MKL_ROOT)/include \
-I$(COMMON_INCLUDES) -I$(PROTONN_INCLUDES) -I$(BONSAI_INCLUDES)
all: ProtoNN ProtoNNPredict Bonsai #ProtoNNIngestTest BonsaiIngestTest
all: ProtoNN ProtoNNPredict Bonsai BonsaiPredict #ProtoNNIngestTest BonsaiIngestTest
libcommon.so: $(COMMON_INCLUDES)
$(MAKE) -C $(SOURCE_DIR)/common
@@ -34,6 +34,12 @@ ProtoNNIngestTest.o: ProtoNNIngestTest.cpp $(PROTONN_INCLUDES)
BonsaiLocalDriver.o:BonsaiLocalDriver.cpp $(BONSAI_INCLUDES)
$(CC) -c -o $@ $(IFLAGS) $(CFLAGS) $<
BonsaiPredictDriver.o:BonsaiPredictDriver.cpp $(BONSAI_INCLUDES)
$(CC) -c -o $@ $(IFLAGS) $(CFLAGS) $<
BonsaiTrainDriver.o:BonsaiTrainDriver.cpp $(BONSAI_INCLUDES)
$(CC) -c -o $@ $(IFLAGS) $(CFLAGS) $<
BonsaiIngestTest.o:BonsaiIngestTest.cpp $(BONSAI_INCLUDES)
$(CC) -c -o $@ $(IFLAGS) $(CFLAGS) $<
@@ -49,6 +55,12 @@ ProtoNNIngestTest: ProtoNNIngestTest.o libcommon.so libProtoNN.so
Bonsai: BonsaiLocalDriver.o libcommon.so libBonsai.so
$(CC) -o $@ $^ $(CFLAGS) $(MKL_SEQ_LDFLAGS) $(CILK_LDFLAGS)
BonsaiPredict: BonsaiPredictDriver.o libcommon.so libBonsai.so
$(CC) -o $@ $^ $(CFLAGS) $(MKL_SEQ_LDFLAGS) $(CILK_LDFLAGS)
BonsaiTrain: BonsaiTrainDriver.o libcommon.so libBonsai.so
$(CC) -o $@ $^ $(CFLAGS) $(MKL_SEQ_LDFLAGS) $(CILK_LDFLAGS)
BonsaiIngestTest: BonsaiIngestTest.o libcommon.so libBonsai.so
$(CC) -o $@ $^ $(CFLAGS) $(MKL_PAR_LDFLAGS) $(CILK_LDFLAGS)
View
@@ -47,7 +47,7 @@ iters="-I 100"
# execute Bonsai
########################################################
gdb=" gdb --args"
#gdb=" gdb --args"
executable="./Bonsai"
command=$gdb" "$executable" "$input_format" "$num_features" "$num_labels" "$ntrain" "$ntest" "$projection_dimension" "$tree_depth" "$sigma" "$reg_W" "$reg_Z" "$reg_Theta" "$reg_V" "$sparse_Z" "$sparse_Theta" "$sparse_V" "$sparse_W" "$batch_factor" "$iters" "$input_dir
echo "Running Bonsai with following command: "
View
@@ -151,6 +151,13 @@ namespace EdgeML
const char *const fromModel,
const bool isDense);
///
/// Model Constructor from commandline args
///
BonsaiModel(
std::string modelFile,
const bool isDense);
///
/// Model Constructor from commandline args
///
@@ -544,7 +551,22 @@ namespace EdgeML
MatrixXuf variance; ///< Object to hold variance of the train data from imported model
BonsaiModel model; ///< Object to hold the imported model
Data testData;
dataCount_t numTest;
DataFormat dataformatType;
std::string dataDir;
std::string modelDir;
void setFromArgs(const int argc, const char** argv);
void exitWithHelp();
public:
///
/// Constructor instantiating model from commandline
///
BonsaiPredictor(const int argc,
const char** argv);
///
/// Constructor instantiating model from a trained model
@@ -561,6 +583,11 @@ namespace EdgeML
void importMeanVar(const size_t numBytes,
const char *const fromBuffer);
///
/// Function to import stored Mean and Variance
///
void importMeanVar(std::string meanVarFile);
///
/// Function to Score an incoming Dense Data Point.Not thread safe
///
@@ -622,6 +649,11 @@ namespace EdgeML
const SparseMatrixuf& Ytest,
const std::string& dataDir,
const std::string& currResultsPath);
///
/// Function to predict an entire test dataset
///
void evaluate();
};
}
View
@@ -9,6 +9,23 @@
using namespace EdgeML;
using namespace EdgeML::Bonsai;
BonsaiModel::BonsaiModel(
std::string modelFile,
const bool isDense)
{
std::ifstream infile(modelFile, std::ios::in|std::ios::binary);
assert(infile.is_open());
size_t modelSize;
infile.read((char*)&modelSize, sizeof(modelSize));
infile.close();
infile.open(modelFile, std::ios::in|std::ios::binary);
char* modelBuff = new char[modelSize];
infile.read((char*)modelBuff, modelSize);
infile.close();
(isDense) ? importModel(modelSize, modelBuff) : importSparseModel(modelSize, modelBuff);
}
BonsaiModel::BonsaiModel(
const size_t numBytes,
@@ -45,6 +62,7 @@ size_t BonsaiModel::modelStat()
{
size_t offset = 0;
offset += sizeof(offset);
offset += sizeof(hyperParams);
offset += sizeof(FP_TYPE) * params.Z.rows() * params.Z.cols();
@@ -99,6 +117,9 @@ void BonsaiModel::exportModel(
assert(modelSize == modelStat());
size_t offset = 0;
memcpy(toModel + offset, (void *)&modelSize, sizeof(modelSize));
offset += sizeof(modelSize);
memcpy(toModel + offset, (void *)&hyperParams, sizeof(hyperParams));
offset += sizeof(hyperParams);
@@ -156,6 +177,10 @@ void BonsaiModel::importModel(
size_t offset = 0;
size_t modelSize;
memcpy((void *)&modelSize, fromModel + offset, sizeof(modelSize));
offset += sizeof(modelSize);
memcpy((void *)&hyperParams, fromModel + offset, sizeof(hyperParams));
offset += sizeof(hyperParams);
@@ -211,7 +236,7 @@ void BonsaiModel::importModel(
size_t BonsaiModel::sparseModelStat()
{
return sizeof(hyperParams) + sparseExportStat(params.Z) + sparseExportStat(params.W) +
return sizeof(size_t) + sizeof(hyperParams) + sparseExportStat(params.Z) + sparseExportStat(params.W) +
sparseExportStat(params.V) + sparseExportStat(params.Theta);
}
@@ -223,6 +248,9 @@ void BonsaiModel::exportSparseModel(
size_t offset = 0;
memcpy(toModel + offset, (void *)&modelSize, sizeof(modelSize));
offset += sizeof(modelSize);
memcpy(toModel + offset, (void *)&hyperParams, sizeof(hyperParams));
offset += sizeof(hyperParams);
@@ -270,6 +298,10 @@ void BonsaiModel::importSparseModel(
const char *const fromModel)
{
size_t offset = 0;
size_t modelSize;
memcpy((void *)&modelSize, fromModel + offset, sizeof(modelSize));
offset += sizeof(modelSize);
memcpy((void *)&hyperParams, fromModel + offset, sizeof(hyperParams));
offset += sizeof(hyperParams);
@@ -1,12 +1,94 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include "blas_routines.h"
#include "blas_routines.h"
#include "Bonsai.h"
using namespace EdgeML;
using namespace EdgeML::Bonsai;
void BonsaiPredictor::exitWithHelp()
{
LOG_INFO("./BonsaiPredictor [Options] \n");
LOG_INFO("Options:");
LOG_INFO("-f : [Required] Input format. Takes two values [0 and 1]. 0 is for libsvmFormat(default), 1 is for tab/space separated input.");
LOG_INFO("-N : [Required] Number of data points in the test data.");
LOG_INFO("-D : [Required] Directory of data with test.txt present in it.");
LOG_INFO("-M : [Required] Directory of the Model (loadableModel and loadableMeanVar) .");
exit(1);
}
void BonsaiPredictor::setFromArgs(
const int argc,
const char** argv)
{
int tempFormat;
int required = 0;
for(int i = 1; i < argc; i++) {
if(i % 2 == 1)
assert(argv[i][0] == '-');
else {
switch(argv[i-1][1]) {
case 'f':
tempFormat = int(atoi(argv[i]));
required++;
if (tempFormat == 0) dataformatType = DataFormat::libsvmFormat;
else if (tempFormat == 1) dataformatType = DataFormat::interfaceIngestFormat;
else exitWithHelp();
break;
case 'N':
numTest = int(atoi(argv[i]));
required++;
break;
case 'M':
modelDir = argv[i];
required++;
break;
case 'D':
dataDir = argv[i];
required++;
break;
default:
LOG_INFO("Unknown option: " + std::to_string(argv[i - 1][1]));
exitWithHelp();
break;
}
}
}
if(required != 4) exitWithHelp();
}
BonsaiPredictor::BonsaiPredictor(
const int argc,
const char** argv)
{
setFromArgs(argc, argv);
std::string modelFile = modelDir + "/loadableModel";
model = BonsaiModel(modelFile, 1);
feedDataValBuffer = new FP_TYPE[model.hyperParams.dataDimension];
feedDataFeatureBuffer = new labelCount_t[model.hyperParams.dataDimension];
mean = MatrixXuf::Zero(model.hyperParams.dataDimension, 1);
variance = MatrixXuf::Zero(model.hyperParams.dataDimension, 1);
std::string meanVarFile = modelDir + "/loadableMeanVar";
importMeanVar(meanVarFile);
testData = Data(FileIngest,
DataFormatParams{0, 0, numTest, model.hyperParams.numClasses, model.hyperParams.dataDimension});
if(model.hyperParams.dataformatType != dataformatType)
LOG_INFO("WARNING: The Train and Test input formats don't match.");
testData.loadDataFromFile(dataformatType, "", "", dataDir + "/test.txt");
evaluate();
}
BonsaiPredictor::BonsaiPredictor(
const size_t numBytes,
const char *const fromModel,
@@ -20,11 +102,34 @@ BonsaiPredictor::BonsaiPredictor(
variance = MatrixXuf::Zero(model.hyperParams.dataDimension, 1);
}
void BonsaiPredictor::importMeanVar(
std::string meanVarFile)
{
size_t meanVarSize;
std::ifstream infileMeanVar(meanVarFile, std::ios::in|std::ios::binary);
assert(infileMeanVar.is_open());
infileMeanVar.read((char*)&meanVarSize, sizeof(meanVarSize));
infileMeanVar.close();
infileMeanVar.open(meanVarFile, std::ios::in|std::ios::binary);
char* meanVarBuff = new char[meanVarSize];
infileMeanVar.read((char*)meanVarBuff, meanVarSize);
infileMeanVar.close();
importMeanVar(meanVarSize, meanVarBuff);
}
void BonsaiPredictor::importMeanVar(
const size_t numBytes,
const char *const fromBuffer)
{
size_t offset = 0;
size_t meanVarSize;
memcpy((void *)&meanVarSize, fromBuffer + offset, sizeof(meanVarSize));
offset += sizeof(meanVarSize);
memcpy(mean.data(), fromBuffer + offset, sizeof(FP_TYPE) * mean.rows() * mean.cols());
offset += sizeof(FP_TYPE) * mean.rows() * mean.cols();
memcpy(variance.data(), fromBuffer + offset, sizeof(FP_TYPE) * variance.rows() * variance.cols());
@@ -151,6 +256,11 @@ void BonsaiPredictor::scoreDenseDataPoint(
predictionScore(dataPoint, scores);
}
void BonsaiPredictor::evaluate()
{
batchEvaluate(testData.Xtest, testData.Ytest, dataDir, modelDir);
}
void BonsaiPredictor::batchEvaluate(
const SparseMatrixuf& Xtest,
const SparseMatrixuf& Ytest,
Oops, something went wrong.

0 comments on commit 89da7e9

Please sign in to comment.