From 312d5614abc13204e69034c72d58781168c86822 Mon Sep 17 00:00:00 2001 From: Sergey Dolgov Date: Thu, 17 Aug 2023 16:38:26 +0100 Subject: [PATCH 1/2] Matlab webwrite can be much faster than http.send. As a by-product, tidy up http request code --- clients/matlab/ttClient.m | 15 +++++++++++---- matlab/@HTTPModel/HTTPModel.m | 17 +++++++++++------ matlab/@HTTPModel/apply_hessian.m | 12 +++--------- matlab/@HTTPModel/apply_jacobian.m | 12 +++--------- matlab/@HTTPModel/evaluate.m | 15 +++++---------- matlab/@HTTPModel/get_model_info.m | 11 ++--------- matlab/@HTTPModel/gradient.m | 12 +++--------- matlab/@HTTPModel/send_data.m | 16 ++++++++++++++++ matlab/umbridge_supported_models.m | 9 ++++----- 9 files changed, 58 insertions(+), 61 deletions(-) create mode 100644 matlab/@HTTPModel/send_data.m diff --git a/clients/matlab/ttClient.m b/clients/matlab/ttClient.m index 4abc2f8..2db720e 100644 --- a/clients/matlab/ttClient.m +++ b/clients/matlab/ttClient.m @@ -1,11 +1,18 @@ +% Analytic-Banana benchmark. Approximate log-posterior density in TT format % Check for (and download) TT Toolbox check_tt; uri = 'http://localhost:4243'; -model = HTTPModel(uri,'posterior'); +model = HTTPModel(uri, 'posterior'); % TT demo with umbridge model -tol = 1e-6; -x = linspace(-5,5,33); -TTlogLikelihood = amen_cross(numel(x)*ones(2,1), @(i)model.evaluate(x(i)), tol, 'vec', false) +tol = 1e-5; +d = model.get_input_sizes +x = linspace(-5,5,33); % A uniform grid on [-5,5]^d for analytic-banana +% TTlogLikelihood = amen_cross(numel(x)*ones(d,1), @(i)model.evaluate(x(i)), tol, 'vec', false) +tic; +TTlogLikelihood = greedy2_cross(numel(x)*ones(d,1), @(i)model.evaluate(x(i)), tol, 'vec', false) +toc +% benchmark-analytic-banana: 44.138067 seconds with 'send' engine +% 4.250689 seconds with 'webwrite' engine diff --git a/matlab/@HTTPModel/HTTPModel.m b/matlab/@HTTPModel/HTTPModel.m index d725169..332447c 100644 --- a/matlab/@HTTPModel/HTTPModel.m +++ b/matlab/@HTTPModel/HTTPModel.m @@ -3,22 +3,26 @@ properties uri model_name + send_engine % 'send' or 'webwrite' end methods - function model = HTTPModel(uri,model_name) - import matlab.net.* - import matlab.net.http.* - + function model = HTTPModel(uri,model_name,send_engine) model.uri = uri; model.model_name = model_name; + if (nargin<3) || (isempty(send_engine)) + model.send_engine = 'send'; + else + model.send_engine = send_engine; + end % check protocol, make sure it's matching - r = RequestMessage; - uri = URI([uri, '/Info']); + uri = matlab.net.URI([uri, '/Info']); + r = matlab.net.http.RequestMessage; % This must be GET resp = send(r,uri); HTTPModel.check_http_status(resp); % check if connection broke down json = jsondecode(resp.Body.string); + if json.protocolVersion ~= 1 error('the protocol version on the server side does not match the client') end @@ -45,6 +49,7 @@ methods (Access=private) output_json = get_model_info(self); + output_json = send_data(self, uri, value); end methods (Static, Access=public) diff --git a/matlab/@HTTPModel/apply_hessian.m b/matlab/@HTTPModel/apply_hessian.m index 8170855..1541cf4 100644 --- a/matlab/@HTTPModel/apply_hessian.m +++ b/matlab/@HTTPModel/apply_hessian.m @@ -12,11 +12,7 @@ config = struct; end -import matlab.net.* -import matlab.net.http.* - % Evaluate model -r = RequestMessage('POST'); if (isa(input, 'cell')) value.input = input; elseif (isa(input, 'double')) @@ -35,11 +31,9 @@ value.inWrt2 = inWrt2; value.outWrt = outWrt; value.config = config; -r.Body = MessageBody(jsonencode(value)); -uri = URI([self.uri, '/ApplyHessian']); -resp = send(r,uri); -self.check_http_status(resp); -json = jsondecode(resp.Body.string); +value = jsonencode(value); +uri = matlab.net.URI([self.uri, '/ApplyHessian']); +json = self.send_data(uri, value); self.check_error(json); output = json.output; diff --git a/matlab/@HTTPModel/apply_jacobian.m b/matlab/@HTTPModel/apply_jacobian.m index 58e641c..684cf8a 100644 --- a/matlab/@HTTPModel/apply_jacobian.m +++ b/matlab/@HTTPModel/apply_jacobian.m @@ -9,11 +9,7 @@ config = struct; end -import matlab.net.* -import matlab.net.http.* - % Evaluate model -r = RequestMessage('POST'); if (isa(input, 'cell')) value.input = input; elseif (isa(input, 'double')) @@ -30,11 +26,9 @@ value.inWrt = inWrt; value.outWrt = outWrt; value.config = config; -r.Body = MessageBody(jsonencode(value)); -uri = URI([self.uri, '/ApplyJacobian']); -resp = send(r,uri); -self.check_http_status(resp); -json = jsondecode(resp.Body.string); +value = jsonencode(value); +uri = matlab.net.URI([self.uri, '/ApplyJacobian']); +json = self.send_data(uri, value); self.check_error(json); output = json.output; diff --git a/matlab/@HTTPModel/evaluate.m b/matlab/@HTTPModel/evaluate.m index f848c2c..d9db9f4 100644 --- a/matlab/@HTTPModel/evaluate.m +++ b/matlab/@HTTPModel/evaluate.m @@ -3,11 +3,7 @@ config = struct; end -import matlab.net.* -import matlab.net.http.* - -% Evaluate model -r = RequestMessage('POST'); +% Parse inputs if (isa(input, 'cell')) value.input = input; elseif (isa(input, 'double')) @@ -21,11 +17,10 @@ end value.name = self.model_name; value.config = config; -r.Body = MessageBody(jsonencode(value)); -uri = URI([self.uri, '/Evaluate']); -resp = send(r,uri); -self.check_http_status(resp); -json = jsondecode(resp.Body.string); +value = jsonencode(value); +uri = matlab.net.URI([self.uri, '/Evaluate']); +% Evaluate model +json = self.send_data(uri, value); self.check_error(json); output = json.output; diff --git a/matlab/@HTTPModel/get_model_info.m b/matlab/@HTTPModel/get_model_info.m index d605cd0..291f6bf 100644 --- a/matlab/@HTTPModel/get_model_info.m +++ b/matlab/@HTTPModel/get_model_info.m @@ -1,15 +1,8 @@ function [output_json] = get_model_info(self) -import matlab.net.* -import matlab.net.http.* - -r = RequestMessage('POST'); value.name = self.model_name; -r.Body = MessageBody(jsonencode(value)); -uri = URI([self.uri,'/ModelInfo']); -resp = send(r,uri); -self.check_http_status(resp); % check if connection broke down -json = jsondecode(resp.Body.string); +uri = matlab.net.URI([self.uri,'/ModelInfo']); +json = self.send_data(uri, jsonencode(value)); self.check_error(json); % check if message came in but contains an error output_json = json.support; diff --git a/matlab/@HTTPModel/gradient.m b/matlab/@HTTPModel/gradient.m index dc593ed..c940824 100644 --- a/matlab/@HTTPModel/gradient.m +++ b/matlab/@HTTPModel/gradient.m @@ -9,11 +9,7 @@ config = struct; end -import matlab.net.* -import matlab.net.http.* - % Evaluate model -r = RequestMessage('POST'); if (isa(input, 'cell')) value.input = input; elseif (isa(input, 'double')) @@ -30,11 +26,9 @@ value.inWrt = inWrt; value.outWrt = outWrt; value.config = config; -r.Body = MessageBody(jsonencode(value)); -uri = URI([self.uri, '/Gradient']); -resp = send(r,uri); -self.check_http_status(resp); -json = jsondecode(resp.Body.string); +value = jsonencode(value); +uri = matlab.net.URI([self.uri, '/Gradient']); +json = self.send_data(uri, value); self.check_error(json); output = json.output; diff --git a/matlab/@HTTPModel/send_data.m b/matlab/@HTTPModel/send_data.m new file mode 100644 index 0000000..ce86fac --- /dev/null +++ b/matlab/@HTTPModel/send_data.m @@ -0,0 +1,16 @@ +function output_json = send_data(self, uri, value) +if strcmpi(self.send_engine, 'send') + r = matlab.net.http.RequestMessage('POST'); + r.Body = matlab.net.http.MessageBody(value); + resp = send(r, uri); + self.check_http_status(resp); + output_json = jsondecode(resp.Body.string); +else + opts = weboptions('Timeout', inf, 'RequestMethod', 'POST'); + opts.MediaType = 'application/json'; + output_json = webwrite(uri, value, opts); + if ~isa(output_json, 'struct') + output_json = jsondecode(output_json); + end +end +end \ No newline at end of file diff --git a/matlab/umbridge_supported_models.m b/matlab/umbridge_supported_models.m index e619a9b..8b6c0bf 100644 --- a/matlab/umbridge_supported_models.m +++ b/matlab/umbridge_supported_models.m @@ -1,13 +1,12 @@ function [model_names] = umbridge_supported_models(uri) -import matlab.net.* -import matlab.net.http.* - % Get model info -r = RequestMessage; -uri = URI([uri, '/Info']); +uri = matlab.net.URI([uri, '/Info']); + +r = matlab.net.http.RequestMessage; % This needs to be GET resp = send(r,uri); HTTPModel.check_http_status(resp); % check if connection broke down json = jsondecode(resp.Body.string); + HTTPModel.check_error(json); % check if message came in but contains an error model_names = json.models; From 94e2c56e6d69c098734e06385957e8bdba35ad1f Mon Sep 17 00:00:00 2001 From: reinarz Date: Mon, 21 Aug 2023 10:49:02 +0100 Subject: [PATCH 2/2] add julia client example --- julia/juliaClient.jl | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 julia/juliaClient.jl diff --git a/julia/juliaClient.jl b/julia/juliaClient.jl new file mode 100644 index 0000000..778ca99 --- /dev/null +++ b/julia/juliaClient.jl @@ -0,0 +1,8 @@ +using UMBridge + +url = "http://localhost:4242" + +val = UMBridge.evaluate(url, "forward" ,[[1,3]], Dict()) + +print(val) +