From 2c8090c44169e1db170b57e4589e9454717a3fcc Mon Sep 17 00:00:00 2001 From: Wei-Sheng Chin Date: Thu, 4 Apr 2019 20:14:51 -0700 Subject: [PATCH 1/3] Fix marshalling of bool flags in MF --- .../SafeTrainingAndModelBuffer.cs | 16 ++++++++-------- src/Native/MatrixFactorizationNative/libmf | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs b/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs index 9bd70d9e1a..fd80cc216f 100644 --- a/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs +++ b/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs @@ -133,19 +133,19 @@ private struct MFParameter /// Specify if the factor matrices should be non-negative. /// [FieldOffset(48)] - public int DoNmf; + public byte DoNmf; /// /// Set to true so that LIBMF may produce less information to STDOUT. /// - [FieldOffset(52)] - public int Quiet; + [FieldOffset(49)] + public byte Quiet; /// /// Set to false so that LIBMF may reuse and modifiy the data passed in. /// - [FieldOffset(56)] - public int CopyData; + [FieldOffset(50)] + public byte CopyData; } [StructLayout(LayoutKind.Explicit)] @@ -223,9 +223,9 @@ public SafeTrainingAndModelBuffer(IHostEnvironment env, int fun, int k, int nrTh _mfParam.Eta = (float)eta; _mfParam.Alpha = (float)alpha; _mfParam.C = (float)c; - _mfParam.DoNmf = doNmf ? 1 : 0; - _mfParam.Quiet = quiet ? 1 : 0; - _mfParam.CopyData = copyData ? 1 : 0; + _mfParam.DoNmf = doNmf ? (byte)1 : (byte)0; + _mfParam.Quiet = quiet ? (byte)1 : (byte)0; + _mfParam.CopyData = copyData ? (byte)1 : (byte)0; } ~SafeTrainingAndModelBuffer() diff --git a/src/Native/MatrixFactorizationNative/libmf b/src/Native/MatrixFactorizationNative/libmf index 5b055ea473..8262f339db 160000 --- a/src/Native/MatrixFactorizationNative/libmf +++ b/src/Native/MatrixFactorizationNative/libmf @@ -1 +1 @@ -Subproject commit 5b055ea473756bd14f56b49db7e0483271788cc2 +Subproject commit 8262f339dba0792bf0f3892bae92b3dd4432afc5 From fbbc1215bf265a00ccab64ced2d02d82ca05d616 Mon Sep 17 00:00:00 2001 From: Wei-Sheng Chin Date: Fri, 5 Apr 2019 10:46:04 -0700 Subject: [PATCH 2/3] Address comment --- .../SafeTrainingAndModelBuffer.cs | 12 +++--- .../UnmanagedMemory.cpp | 37 +++++++++++++++---- .../UnmanagedMemory.h | 25 +++++++++++-- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs b/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs index fd80cc216f..1f25b2fc60 100644 --- a/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs +++ b/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs @@ -133,19 +133,19 @@ private struct MFParameter /// Specify if the factor matrices should be non-negative. /// [FieldOffset(48)] - public byte DoNmf; + public sbyte DoNmf; /// /// Set to true so that LIBMF may produce less information to STDOUT. /// [FieldOffset(49)] - public byte Quiet; + public sbyte Quiet; /// /// Set to false so that LIBMF may reuse and modifiy the data passed in. /// [FieldOffset(50)] - public byte CopyData; + public sbyte CopyData; } [StructLayout(LayoutKind.Explicit)] @@ -223,9 +223,9 @@ public SafeTrainingAndModelBuffer(IHostEnvironment env, int fun, int k, int nrTh _mfParam.Eta = (float)eta; _mfParam.Alpha = (float)alpha; _mfParam.C = (float)c; - _mfParam.DoNmf = doNmf ? (byte)1 : (byte)0; - _mfParam.Quiet = quiet ? (byte)1 : (byte)0; - _mfParam.CopyData = copyData ? (byte)1 : (byte)0; + _mfParam.DoNmf = doNmf ? (sbyte)1 : (sbyte)0; + _mfParam.Quiet = quiet ? (sbyte)1 : (sbyte)0; + _mfParam.CopyData = copyData ? (sbyte)1 : (sbyte)0; } ~SafeTrainingAndModelBuffer() diff --git a/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp b/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp index 6f93cf817e..5dba645331 100644 --- a/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp +++ b/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp @@ -9,25 +9,48 @@ using namespace mf; +EXPORT_API(mf_parameter) make_param(const mf_parameter_bridge *param_bridge) +{ + mf_parameter param; + param.fun = param_bridge->fun; + param.k = param_bridge->k; + param.nr_threads = param_bridge->nr_threads; + param.nr_bins = param_bridge->nr_bins; + param.nr_iters = param_bridge->nr_iters; + param.lambda_p1 = param_bridge->lambda_p1; + param.lambda_p2 = param_bridge->lambda_p2; + param.lambda_q1 = param_bridge->lambda_q1; + param.lambda_q2 = param_bridge->lambda_q2; + param.eta = param_bridge->eta; + param.alpha = param_bridge->alpha; + param.c = param_bridge->c; + param.do_nmf = static_cast(param_bridge->do_nmf); + param.quiet = static_cast(param_bridge->quiet); + param.copy_data = static_cast(param_bridge->copy_data); + return param; +} + EXPORT_API(void) MFDestroyModel(mf_model *&model) { return mf_destroy_model(&model); } -EXPORT_API(mf_model*) MFTrain(const mf_problem *prob, const mf_parameter *param) +EXPORT_API(mf_model*) MFTrain(const mf_problem *prob, const mf_parameter_bridge *param_bridge) { - return mf_train(prob, *param); + auto param = make_param(param_bridge); + return mf_train(prob, param); } -EXPORT_API(mf_model*) MFTrainWithValidation(const mf_problem *tr, const mf_problem *va, const mf_parameter *param) +EXPORT_API(mf_model*) MFTrainWithValidation(const mf_problem *tr, const mf_problem *va, const mf_parameter_bridge *param_bridge) { - return mf_train_with_validation(tr, va, *param); + auto param = make_param(param_bridge); + return mf_train_with_validation(tr, va, param); } - -EXPORT_API(float) MFCrossValidation(const mf_problem *prob, int nr_folds, const mf_parameter *param) +EXPORT_API(float) MFCrossValidation(const mf_problem *prob, int nr_folds, const mf_parameter_bridge *param_bridge) { - return mf_cross_validation(prob, nr_folds, *param); + auto param = make_param(param_bridge); + return mf_cross_validation(prob, nr_folds, param); } EXPORT_API(float) MFPredict(const mf_model *model, int p_idx, int q_idx) diff --git a/src/Native/MatrixFactorizationNative/UnmanagedMemory.h b/src/Native/MatrixFactorizationNative/UnmanagedMemory.h index 6007d35e30..ff7edd3bd1 100644 --- a/src/Native/MatrixFactorizationNative/UnmanagedMemory.h +++ b/src/Native/MatrixFactorizationNative/UnmanagedMemory.h @@ -8,12 +8,31 @@ using namespace mf; +struct mf_parameter_bridge +{ + int32_t fun; + int32_t k; + int32_t nr_threads; + int32_t nr_bins; + int32_t nr_iters; + float lambda_p1; + float lambda_p2; + float lambda_q1; + float lambda_q2; + float eta; + float alpha; + float c; + int8_t do_nmf; + int8_t quiet; + int8_t copy_data; +}; + EXPORT_API(void) MFDestroyModel(mf_model *&model); -EXPORT_API(mf_model*) MFTrain(const mf_problem *prob, const mf_parameter *param); +EXPORT_API(mf_model*) MFTrain(const mf_problem *prob, const mf_parameter_bridge *parameter_bridge); -EXPORT_API(mf_model*) MFTrainWithValidation(const mf_problem *tr, const mf_problem *va, const mf_parameter *param); +EXPORT_API(mf_model*) MFTrainWithValidation(const mf_problem *tr, const mf_problem *va, const mf_parameter_bridge *parameter_bridge); -EXPORT_API(float) MFCrossValidation(const mf_problem *prob, int nr_folds, const mf_parameter* param); +EXPORT_API(float) MFCrossValidation(const mf_problem *prob, int nr_folds, const mf_parameter_bridge* parameter_bridge); EXPORT_API(float) MFPredict(const mf_model *model, int p_idx, int q_idx); From 1bcdc54cf0f40e73927c17168acd392a52bebbb2 Mon Sep 17 00:00:00 2001 From: Wei-Sheng Chin Date: Fri, 5 Apr 2019 13:44:01 -0700 Subject: [PATCH 3/3] Better type of C# and C bool bridge --- .../SafeTrainingAndModelBuffer.cs | 12 ++++++------ .../MatrixFactorizationNative/UnmanagedMemory.cpp | 8 ++++---- .../MatrixFactorizationNative/UnmanagedMemory.h | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs b/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs index 1f25b2fc60..fd80cc216f 100644 --- a/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs +++ b/src/Microsoft.ML.Recommender/SafeTrainingAndModelBuffer.cs @@ -133,19 +133,19 @@ private struct MFParameter /// Specify if the factor matrices should be non-negative. /// [FieldOffset(48)] - public sbyte DoNmf; + public byte DoNmf; /// /// Set to true so that LIBMF may produce less information to STDOUT. /// [FieldOffset(49)] - public sbyte Quiet; + public byte Quiet; /// /// Set to false so that LIBMF may reuse and modifiy the data passed in. /// [FieldOffset(50)] - public sbyte CopyData; + public byte CopyData; } [StructLayout(LayoutKind.Explicit)] @@ -223,9 +223,9 @@ public SafeTrainingAndModelBuffer(IHostEnvironment env, int fun, int k, int nrTh _mfParam.Eta = (float)eta; _mfParam.Alpha = (float)alpha; _mfParam.C = (float)c; - _mfParam.DoNmf = doNmf ? (sbyte)1 : (sbyte)0; - _mfParam.Quiet = quiet ? (sbyte)1 : (sbyte)0; - _mfParam.CopyData = copyData ? (sbyte)1 : (sbyte)0; + _mfParam.DoNmf = doNmf ? (byte)1 : (byte)0; + _mfParam.Quiet = quiet ? (byte)1 : (byte)0; + _mfParam.CopyData = copyData ? (byte)1 : (byte)0; } ~SafeTrainingAndModelBuffer() diff --git a/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp b/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp index 5dba645331..75b6ccac93 100644 --- a/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp +++ b/src/Native/MatrixFactorizationNative/UnmanagedMemory.cpp @@ -9,7 +9,7 @@ using namespace mf; -EXPORT_API(mf_parameter) make_param(const mf_parameter_bridge *param_bridge) +mf_parameter make_param(const mf_parameter_bridge *param_bridge) { mf_parameter param; param.fun = param_bridge->fun; @@ -24,9 +24,9 @@ EXPORT_API(mf_parameter) make_param(const mf_parameter_bridge *param_bridge) param.eta = param_bridge->eta; param.alpha = param_bridge->alpha; param.c = param_bridge->c; - param.do_nmf = static_cast(param_bridge->do_nmf); - param.quiet = static_cast(param_bridge->quiet); - param.copy_data = static_cast(param_bridge->copy_data); + param.do_nmf = param_bridge->do_nmf != 0 ? true : false; + param.quiet = param_bridge->quiet != 0 ? true : false; + param.copy_data = param_bridge->copy_data != 0 ? true : false; return param; } diff --git a/src/Native/MatrixFactorizationNative/UnmanagedMemory.h b/src/Native/MatrixFactorizationNative/UnmanagedMemory.h index ff7edd3bd1..2b07d7843b 100644 --- a/src/Native/MatrixFactorizationNative/UnmanagedMemory.h +++ b/src/Native/MatrixFactorizationNative/UnmanagedMemory.h @@ -22,9 +22,9 @@ struct mf_parameter_bridge float eta; float alpha; float c; - int8_t do_nmf; - int8_t quiet; - int8_t copy_data; + uint8_t do_nmf; + uint8_t quiet; + uint8_t copy_data; }; EXPORT_API(void) MFDestroyModel(mf_model *&model);