Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions examples/parallel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# parfor Example
This example can only run if Parallel Computing Toolbox is installed. It shows how to instrument a parfor loop using spans. parfor is a function in Parallel Computing Toolbox that implements a parallel for-loop. It performs its iterations in parallel by sending them to workers in a parallel pool. The instrumented code loops through a series of random matrices and compute their maximum eigenvalue.
* At the beginning of the first run, initialization is necessary to create and store a global tracer provider.
* Initialization is also necessary in the parfor block, as this code is run in separate workers and each worker needs to run the initialization during the first run.
* A span is created both before and inside the parfor block.
* To have all the spans form a single trace, context has to be passed explicitly into the parfor block.

## Running the Example
1. Start an instance of [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector).
2. Start MATLAB.
3. Make sure Parallel Computing Toolbox is installed by typing the command "ver parallel".
3. Ensure the installation directory of OpenTelemetry-matlab is on the MATLAB path.
4. Run parfor\_example. By default, MATLAB automatically opens a parallel pool of workers on your local machine.
5. Run parfor\_example again. The second run should be faster than the first run because the parallel pool takes some time to start up.
65 changes: 65 additions & 0 deletions examples/parallel/parfor_example.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
function a = parfor_example
% This example creates a trace through a parfor loop, by creating a span in
% each iteration and propagating context.
%
% Copyright 2024 The MathWorks, Inc.

% initialize tracing
runOnce(@initTracer);

% start the top level span and make it current
tr = opentelemetry.trace.getTracer("parfor_example");
sp = startSpan(tr, "main function");
scope = makeCurrent(sp); %#ok<*NASGU>

n = 80;
A = 500;
a = zeros(1,n); % initialize the output
nworkers = 4; % maximum number of workers

% propagate the current context by extracting and passing it in headers
carrier = opentelemetry.context.propagation.injectContext();
headers = carrier.Headers;

parfor (i = 1:n, nworkers)
% parfor block needs its own initialization
runOnce(@initTracer);

% extract context from headers and make it current
carrier = opentelemetry.context.propagation.TextMapCarrier(headers);
newcontext = opentelemetry.context.propagation.extractContext(carrier);
scope_i = setCurrentContext(newcontext);

% start a span for this iteration
tr_i = opentelemetry.trace.getTracer("parfor_example");
sp_i = startSpan(tr_i, "Iteration" + i);

% compute the maximum eigenvalue of a random matrix
a(i) = max(abs(eig(rand(A))));

% end the scope and the span
scope_i = [];
endSpan(sp_i);
end
end

function initTracer
% set up global TracerProvider
resource = dictionary("service.name", "OpenTelemetry-Matlab_examples");
tp = opentelemetry.sdk.trace.TracerProvider(...
opentelemetry.sdk.trace.SimpleSpanProcessor, Resource=resource);
setTracerProvider(tp);

% set up global propagator
prop = opentelemetry.trace.propagation.TraceContextPropagator();
setTextMapPropagator(prop);
end

% This helper ensures the input function is only run once
function runOnce(fh)
persistent hasrun
if isempty(hasrun)
feval(fh);
hasrun = 1;
end
end