MPSolver can accept protocol buffers as input and as output, examples in examples/linear_solver_example_with_protocol_buffers.cc
This commit is contained in:
@@ -48,7 +48,8 @@ cpexe: $(CPBINARIES)
|
||||
|
||||
LPBINARIES = \
|
||||
integer_solver_example$E \
|
||||
linear_solver_example$E
|
||||
linear_solver_example$E \
|
||||
linear_solver_example_with_protocol_buffers$E
|
||||
|
||||
lpexe: $(LPBINARIES)
|
||||
|
||||
@@ -492,6 +493,12 @@ objs/linear_solver_example.$O: examples/linear_solver_example.cc
|
||||
linear_solver_example$E: $(LP_LIBS) $(BASE_LIBS) objs/linear_solver_example.$O
|
||||
$(CCC) $(CFLAGS) $(LDFLAGS) objs/linear_solver_example.$O $(LP_LIBS) $(BASE_LIBS) $(LDLPDEPS) $(EXEOUT)linear_solver_example$E
|
||||
|
||||
objs/linear_solver_example_with_protocol_buffers.$O: examples/linear_solver_example_with_protocol_buffers.cc
|
||||
$(CCC) $(CFLAGS) -c examples/linear_solver_example_with_protocol_buffers.cc $(OBJOUT)objs/linear_solver_example_with_protocol_buffers.$O
|
||||
|
||||
linear_solver_example_with_protocol_buffers$E: $(LP_LIBS) $(BASE_LIBS) objs/linear_solver_example_with_protocol_buffers.$O
|
||||
$(CCC) $(CFLAGS) $(LDFLAGS) objs/linear_solver_example_with_protocol_buffers.$O $(LP_LIBS) $(BASE_LIBS) $(LDLPDEPS) $(EXEOUT)linear_solver_example_with_protocol_buffers$E
|
||||
|
||||
objs/integer_solver_example.$O: examples/integer_solver_example.cc
|
||||
$(CCC) $(CFLAGS) -c examples/integer_solver_example.cc $(OBJOUT)objs/integer_solver_example.$O
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "base/map-util.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/hash.h"
|
||||
|
||||
#include "linear_solver/linear_solver.pb.h"
|
||||
|
||||
DEFINE_string(solver_write_model, "", "path of the file to write the model to");
|
||||
@@ -503,7 +504,8 @@ void MPSolver::ExportModel(MPModelProto* model) const {
|
||||
// Encode current solution in a solution response protocol buffer.
|
||||
void MPSolver::FillSolutionResponse(MPSolutionResponse* response) const {
|
||||
CHECK_NOTNULL(response);
|
||||
if (response->has_result_status() ||
|
||||
if ((response->has_result_status() &&
|
||||
response->result_status() != MPSolutionResponse::NOT_SOLVED) ||
|
||||
response->has_objective_value() ||
|
||||
response->solution_values_size() > 0) {
|
||||
LOG(WARNING) << "The solution response is not empty, "
|
||||
|
||||
@@ -286,8 +286,6 @@ class MPSolver {
|
||||
virtual ~MPSolver();
|
||||
|
||||
// ----- Methods using protocol buffers -----
|
||||
#ifndef SWIG
|
||||
// TODO(user): fix swig support.
|
||||
|
||||
// Loads model from protocol buffer.
|
||||
LoadStatus LoadModel(const MPModelProto& model);
|
||||
@@ -304,7 +302,6 @@ class MPSolver {
|
||||
// of MPSolver, MPModelRequest.OptimizationProblemType is ignored.
|
||||
void SolveWithProtocolBuffers(const MPModelRequest& model_request,
|
||||
MPSolutionResponse* response);
|
||||
#endif
|
||||
|
||||
// ----- Init and Clear -----
|
||||
void Init() {} // To remove.
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
// Linear solver Stubby services
|
||||
|
||||
syntax = "proto2";
|
||||
option java_package = "com.google.ortools.linearsolver";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package operations_research;
|
||||
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
%include "base/base.swig"
|
||||
%include base/base.swig
|
||||
%include util/data.swig
|
||||
|
||||
// Include the file we want to wrap a first time.
|
||||
%{
|
||||
#include "linear_solver/linear_solver.h"
|
||||
#include "linear_solver/linear_solver.pb.h"
|
||||
%}
|
||||
|
||||
#ifdef SWIGPYTHON
|
||||
@@ -32,6 +34,12 @@
|
||||
%ignore MakeNumVarArray;
|
||||
%ignore MakeIntVarArray;
|
||||
%ignore MakeBoolVarArray;
|
||||
// The following 3 methods that use protocol buffers as output
|
||||
// arguments are ignored as they are too difficult to wrap and there
|
||||
// is no immediate use case.
|
||||
%ignore ExportModel;
|
||||
%ignore SolveWithProtocolBuffers;
|
||||
%ignore FillSolutionResponse;
|
||||
|
||||
namespace operations_research {
|
||||
%pythoncode {
|
||||
@@ -347,6 +355,7 @@ class LinearConstraint(object):
|
||||
#endif
|
||||
|
||||
#ifdef SWIGJAVA
|
||||
|
||||
%module(directors="1") operations_research;
|
||||
|
||||
namespace operations_research {
|
||||
@@ -392,6 +401,7 @@ namespace operations_research {
|
||||
%rename (clearObjective) MPSolver::ClearObjective;
|
||||
%rename (init) MPSolver::Init;
|
||||
%rename (isLpFormat) MPSolver::IsLPFormat;
|
||||
%rename (loadModel) MPSolver::LoadModel;
|
||||
%rename (makeBoolVar) MPSolver::MakeBoolVar;
|
||||
%rename (makeIntVar) MPSolver::MakeIntVar;
|
||||
%rename (makeNumVar) MPSolver::MakeNumVar;
|
||||
@@ -415,11 +425,19 @@ namespace operations_research {
|
||||
%rename (timeLimit) MPSolver::time_limit;
|
||||
%rename (wallTime) MPSolver::wall_time;
|
||||
%rename (writeModelFilename) MPSolver::write_model_filename;
|
||||
// Ignore code on MPSolver.
|
||||
// Ignore code on MPSolver, see replacement java code below.
|
||||
%ignore MPSolver::MakeVarArray;
|
||||
%ignore MPSolver::MakeNumVarArray;
|
||||
%ignore MPSolver::MakeIntVarArray;
|
||||
%ignore MPSolver::MakeBoolVarArray;
|
||||
// The following 3 methods that use protocol buffers as output
|
||||
// arguments are replaced by methods that return a protocol buffer,
|
||||
// see code below.
|
||||
%ignore MPSolver::ExportModel;
|
||||
%ignore MPSolver::FillSolutionResponse;
|
||||
%ignore MPSolver::SolveWithProtocolBuffers;
|
||||
|
||||
|
||||
// Add java code on MPSolver.
|
||||
%typemap(javacode) MPSolver %{
|
||||
public MPVariable[] makeVarArray(int count,
|
||||
@@ -475,6 +493,7 @@ namespace operations_research {
|
||||
return makeVarArray(count, 0.0, 1.0, true, var_name);
|
||||
}
|
||||
%}
|
||||
|
||||
} // namespace operations_research
|
||||
|
||||
#endif // SWIGJAVA
|
||||
|
||||
@@ -256,6 +256,12 @@ static bool PyCallbackBool(PyObject* pyfunc) {
|
||||
#endif // SWIGPYTHON
|
||||
|
||||
#if defined(SWIGJAVA)
|
||||
|
||||
%{
|
||||
#include "base/jniutil.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
%}
|
||||
|
||||
%module(directors="1") main
|
||||
%feature("director") LongResultCallback1;
|
||||
%feature("director") LongResultCallback2;
|
||||
@@ -395,4 +401,80 @@ class LongResultCallback3 {
|
||||
$1 = &result;
|
||||
}
|
||||
|
||||
// SWIG macros to be used in generating Java wrappers for C++ protocol
|
||||
// message parameters. Each protocol message is serialized into
|
||||
// byte[] before passing into (or returning from) C++ code.
|
||||
|
||||
// If the C++ function expects an input protocol message:
|
||||
// foo(const MyProto* message,...)
|
||||
// Use PROTO_INPUT macro:
|
||||
// PROTO_INPUT(MyProto, com.google.proto.protos.test.MyProto, message)
|
||||
//
|
||||
// if the C++ function returns a protocol message:
|
||||
// MyProto* foo();
|
||||
// Use PROTO2_RETURN_AND_DELETE macro:
|
||||
// PROTO2_RETURN_AND_DELETE(MyProto, com.google.proto.protos.test.MyProto)
|
||||
|
||||
// Passing each protocol message from Java to C++ by value. Each ProtocolMessage
|
||||
// is serialized into byte[] when it is passed from Java to C++, the C++ code
|
||||
// deserializes into C++ native protocol message.
|
||||
//
|
||||
// @param CppProtoType the fully qualified C++ protocol message type
|
||||
// @param JavaProtoType the corresponding fully qualified Java protocol message
|
||||
// type
|
||||
// @param param_name the parameter name
|
||||
%define PROTO_INPUT(CppProtoType, JavaProtoType, param_name)
|
||||
%typemap(jni) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "jbyteArray"
|
||||
%typemap(jtype) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "byte[]"
|
||||
%typemap(jstype) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "JavaProtoType"
|
||||
%typemap(javain) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "$javainput.toByteArray()"
|
||||
%typemap(in) PROTO_TYPE* INPUT (CppProtoType temp),
|
||||
PROTO_TYPE& INPUT (CppProtoType temp) {
|
||||
int proto_size = 0;
|
||||
scoped_array<char> proto_buffer(
|
||||
JNIUtil::MakeCharArray(jenv, $input, &proto_size));
|
||||
bool parsed_ok = temp.ParseFromArray(proto_buffer.get(), proto_size);
|
||||
if (!parsed_ok) {
|
||||
SWIG_JavaThrowException(jenv,
|
||||
SWIG_JavaRuntimeException,
|
||||
"Unable to parse CppProtoType protocol message.");
|
||||
}
|
||||
$1 = &temp;
|
||||
}
|
||||
|
||||
%apply PROTO_TYPE& INPUT { const CppProtoType& param_name }
|
||||
%apply PROTO_TYPE& INPUT { CppProtoType& param_name }
|
||||
%apply PROTO_TYPE* INPUT { const CppProtoType* param_name }
|
||||
%apply PROTO_TYPE* INPUT { CppProtoType* param_name }
|
||||
|
||||
%enddef // end PROTO_INPUT
|
||||
|
||||
%define PROTO2_RETURN(CppProtoType, JavaProtoType, deleteCppReturn)
|
||||
%typemap(jni) CppProtoType* "jbyteArray"
|
||||
%typemap(jtype) CppProtoType* "byte[]"
|
||||
%typemap(jstype) CppProtoType* "JavaProtoType"
|
||||
%typemap(javaout) CppProtoType* {
|
||||
byte[] buf = $jnicall;
|
||||
if (buf == null || buf.length == 0) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JavaProtoType.parseFrom(buf);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw new RuntimeException(
|
||||
"Unable to parse JavaProtoType protocol message.");
|
||||
}
|
||||
}
|
||||
%typemap(out) CppProtoType* {
|
||||
scoped_array<char> buf(new char[$1->ByteSize()]);
|
||||
$1->SerializeWithCachedSizesToArray(reinterpret_cast<uint8*>(buf.get()));
|
||||
$result = JNIUtil::MakeJByteArray(jenv, buf.get(), $1->ByteSize());
|
||||
if (deleteCppReturn) {
|
||||
// To prevent a memory leak.
|
||||
delete $1;
|
||||
$1 = NULL;
|
||||
}
|
||||
}
|
||||
%enddef // end PROTO2_RETURN_AND_DELETE
|
||||
|
||||
#endif // SWIGJAVA
|
||||
|
||||
Reference in New Issue
Block a user