classdef InferenceInfo
    % InferenceInfo   Container for information about a particular call to
    % an inference method
    
    %   Copyright 2018-2021 The MathWorks, Inc.
    
    properties(SetAccess = private)
        % InferenceMethod  Represents the inference method being called
        InferenceMethod(1,1) string
        
        % DataSize  The size of each observation being passed, as a cell
        % array of sizes each inputs
        DataSize(1,:) cell
        
        % MiniBatchSize  The expected number of observations in each batch
        % of data
        MiniBatchSize(1,1) {mustBeNonnegative , mustBeInteger} = 128
        
        % ExecutionEnvironmentRequested  The value of the
        % ExecutionEnvironment option passed in by the user
        ExecutionEnvironmentRequested char
        
        % Precision  Affects the precision used during computations
        Precision
        
        % ActivationLayerName  The name of the layer for which the
        % activations are being requested (in a call to activations)
        ActivationLayerIndex {mustBePositive , mustBeInteger} = []
                
        % Acceleration  Acceleration to use for inference
        Acceleration
        
        % UseMex  Flag indicating if MEX is being used
        UseMex
        
        % RecurrentInferenceRequiresState  Indicates whether or not the
        % inference method requires state updates for recurrent layers
        RecurrentInferenceRequiresState(1,1) logical = false
        
        % StatelessForward   Indicates no state outputs are requested
        StatelessForward(1,1) logical = true
    end
    
    methods
        function this = InferenceInfo( ...
                inferenceMethod, dataSize, miniBatchSize, ...
                numObservations, executionEnvironment, ...
                precision, activationLayerIndex, acceleration, sequenceLength, ...
                statelessForward)
            
            this.InferenceMethod = inferenceMethod;
            this.ExecutionEnvironmentRequested = executionEnvironment;
            this.Acceleration = acceleration;
            this.UseMex = strcmpi(acceleration,"mex");
            
            this.DataSize = dataSize;
            this.MiniBatchSize = min(miniBatchSize, numObservations);
            this.Precision = precision;
            this.ActivationLayerIndex = activationLayerIndex;
            
            this.RecurrentInferenceRequiresState = ...
                (inferenceMethod == "predictAndUpdateState") || ...
                ~isempty(sequenceLength) && isnumeric(sequenceLength);

            if nargin > 9
                this.StatelessForward = statelessForward;
            end
        end
    end
end
