% PBS Base class for PBSPro and Torque clusters

% Copyright 2011-2023 The MathWorks, Inc.

classdef (Hidden) PBS < parallel.cluster.Generic
    properties (Dependent)
        %SubmitArguments Additional options passed to qsub during job submission
        %   SubmitArguments is a string that is passed to the PBS qsub
        %   command when submitting jobs.
        SubmitArguments

        %ProcsPerNode Number of processors on each node of the cluster
        ProcsPerNode
    end

    properties(Hidden, Dependent)
        %UseJobArrays - True if independent jobs with multiple tasks should
        %   be submitted as a PBS job array
        UseJobArrays

        %CommunicatingJobWrapper Script that cluster runs to start workers
        %   When communicating jobs are submitted, this script file is submitted
        %   for execution. The script must contain commands to launch the
        %   communicating job. CommunicatingJobWrapper can be set to several
        %   special values which will automatically be expanded at submission
        %   time. These values are:
        %   'windowsNoDelegate' - use a built-in default wrapper script suitable for PBS
        %                         clusters with worker machines running Windows, where
        %                         mpiexec delegation is not supported.
        %   'unix'              - use a built-in default wrapper script suitable for PBS
        %                         clusters with worker machines running UNIX.
        %
        %   By default, CommunicatingJobWrapper will be set to 'unix' on
        %   unix clients and 'windowsNoDelegate' on Windows clients.
        %
        %   See also parallel.cluster.PBS.OperatingSystem.
        CommunicatingJobWrapper

        ResourceTemplate
    end

    methods
        function val = get.SubmitArguments(obj)
            val = obj.additionalPropertyOrDefault('AdditionalSubmitArgs', '');
        end

        function set.SubmitArguments(obj, val)
            obj.AdditionalProperties.AdditionalSubmitArgs = val;
        end

        function val = get.ProcsPerNode(obj)
            val = obj.additionalPropertyOrDefault('ProcsPerNode', 2);
        end

        function set.ProcsPerNode(obj, val)
            obj.AdditionalProperties.ProcsPerNode = val;
        end

        function val = get.UseJobArrays(obj)
            val = obj.additionalPropertyOrDefault('UseJobArrays', true);
        end

        function set.UseJobArrays(obj, val)
            obj.AdditionalProperties.UseJobArrays = val;
        end

        function val = get.CommunicatingJobWrapper(obj)
            usingSmpd = obj.additionalPropertyOrDefault('UseSmpd', false);
            if usingSmpd
                val = 'smpd';
            else
                val = 'hydra';
            end
        end

        function set.CommunicatingJobWrapper(obj, val)
            arguments
                obj
                val {mustBeTextScalar, mustBeMember(val, ["hydra", "smpd", "default", "mathworks provided script"])}
            end
            if strcmpi(val, 'smpd')
                obj.AdditionalProperties.UseSmpd = true;
            else
                obj.AdditionalProperties.remove('UseSmpd');
            end
        end

        function val = get.ResourceTemplate(~) %#ok<STOUT>
            error(message('parallel:cluster:DeprecatedResourceTemplate'))
        end

        function set.ResourceTemplate(~, ~)
            error(message('parallel:cluster:DeprecatedResourceTemplate'))
        end
    end

    methods (Access = protected)
        function obj = PBS(varargin)
            obj@parallel.cluster.Generic(varargin{:});

            % By default, use the plugins which ship with PCT
            obj.overrideFactoryValue('PluginScriptsLocation', 'parallel.cluster.pbs');

            % Override OperatingSystem to unix, as we only support Linux
            obj.overrideFactoryValue('OperatingSystem', 'unix');
        end
    end

    methods (Access = private)
        function delete(obj)
            delete@handle(obj);
        end
    end
end
