关于 matlab-discover-clusters
面向 MATLAB 并行计算用户的技能,覆盖集群配置文件的发现、导入、检查、设为默认和删除,并指导验证可用性。
主要功能
- 01列出并检查集群配置文件
- 02发现网络及云端集群
- 03导入与导出共享配置文件
- 04设置默认配置并验证
- 05删除过时配置文件
适用场景
- 01查找可提交作业的集群资源
- 02导入管理员提供的 .mlsettings 文件
- 03确认 parcluster 或 parpool 使用的配置
- 04将配置文件分享给同事
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-discover-clusters安装后在 Claude Code 中输入/matlab-discover-clusters确认已加载。
附带文件manifest.yamlscripts/discoverClusters.p
详细介绍
发现 MATLAB 集群
集群配置文件是一组已保存的属性(名称、类型、主机、工作进程数、调度器参数),可让 MATLAB 连接到计算资源。本技能涵盖配置文件的完整生命周期:发现网络上的集群、导入共享配置文件、设置默认配置文件、验证和删除。
适用场景
- 用户询问有哪些并行计算资源、集群或队列可供使用。
- 用户想查找可用于提交作业的集群。
- 用户从管理员处获得了
.mlsettings配置文件,需要导入。 - 用户想列出、检查、设为默认、验证或删除集群配置文件。
- 用户想导出集群配置文件并与同事共享。
- 用户正在调用
parcluster或parpool,想知道将使用哪种资源,或应传入哪个配置文件名称。
不适用场景
- 提交作业(
batch、createJob、submit、parfeval)——本技能仅涵盖到“集群已准备就绪,可供使用”为止。 - 超出配置文件选择范围的池生命周期管理——
parpool启动/关闭、gcp和销毁池属于其他问题。确定传给parpool的配置文件属于本技能范围。 - GPU 或 parfor 工作流——由单独的技能涵盖。
工作流
- 使用
parallel.listProfiles列出现有配置文件,查看已配置的内容。 - 如果用户缺少预期资源,或想搜索其他集群,请使用随附的
discoverClusters脚本发现集群(网络和云)。 - 将集群添加为配置文件——可以根据发现的集群创建配置文件(
saveAsProfile),也可以导入共享的.mlsettings文件(parallel.importProfile)。 - 如果合适,使用
parallel.defaultProfile设置默认配置文件。 - 使用
parallel.validateProfile(R2025a+)或对集群对象调用validate(c)进行验证,然后再依赖该配置文件。传入NumWorkersToUse(例如 2),或先向用户确认——如果不设置此项,将使用集群的全部工作进程数进行验证。 - 使用
parallel.deleteProfile(R2026a+)删除过时的配置文件——请先向用户确认;删除操作不可撤销。
每完成一步,都要先验证再继续——显示更新后的配置文件列表、确认类型/主机/工作进程数,或检查验证报告。
主要函数
| 函数 | 用途 | 起始版本 |
|---|---|---|
parallel.listProfiles | 列出配置文件名称和默认配置文件 | R2022b |
parallel.defaultProfile | 获取或设置默认配置文件 | R2022b |
parallel.importProfile | 从 .mlsettings 导入配置文件 | R2022b |
parallel.exportProfile | 将配置文件导出为 .mlsettings | R2022b |
parcluster | 根据配置文件创建集群对象 | R2022b |
cluster.saveAsProfile | 将集群对象保存为新配置文件 | R2022b |
parallel.validateProfile | 验证配置文件(独立函数) | R2025a |
validate(cluster) | 通过集群对象进行验证 | R2026a |
parallel.deleteProfile | 按名称删除配置文件 | R2026a |
discoverClusters | 随本技能提供——发现 MJS / Generic / HPCServer / MJSComputeCloud | scripts/discoverClusters.p |
cluster.Type | 属性:"Local"、"Threads"、"MJS"、"MJSComputeCloud"、"Slurm"、"PBSPro"、"LSF"、"HPCServer"、"Generic" | R2022b |
对于高于 R2022b 最低版本要求的功能,请使用模式中注明的备用方案,并向用户说明版本差异。
使用模式
列出和检查配置文件
使用 parallel.listProfiles 获取配置文件名称,并使用 parallel.defaultProfile()(不带参数)读取默认配置文件。若要检查某个配置文件,请调用 parcluster(name) 并读取 cluster.Type(字符串)、cluster.NumWorkers,以及(如适用)cluster.Host。不要解析 class(c)——Type 才是受支持的公开属性。
parcluster(name) 会针对 MJS 配置文件进行一次网络往返,以从调度程序获取实时属性。如果无法访问 MJS,或其发行版不匹配,则会抛出 "Unable to connect to MATLAB Job Scheduler"——这是预期行为,不是代码错误。遍历配置文件时,务必将 parcluster 包在 try/catch 中,并明确区分无法访问的配置文件和不存在的配置文件。
Threads 配置文件无法通过 parcluster 返回——请明确跳过。
使用 strcmp(或两个 string)比较配置文件名称,不要使用 ==:使用 == 比较两个 char 数组会逐字符比较,且当长度不同时会报错。
profiles = parallel.listProfiles;
defaultName = parallel.defaultProfile();
fprintf("\n%-25s %-10s %-10s %s\n", "Profile", "Type", "Workers", "Default");
fprintf("%s\n", repmat('-', 1, 70));
for k = 1:numel(profiles)
name = profiles{k};
marker = "";
if strcmp(name, defaultName); marker = "(default)"; end
if strcmp(name, "Threads")
fprintf("%-25s %-10s %-10s %s\n", name, "Threads", "n/a", marker);
continue
end
try
c = parcluster(name);
fprintf("%-25s %-10s %-10d %s\n", name, string(c.Type), c.NumWorkers, marker);
catch
fprintf("%-25s %-10s %-10s %s\n", name, "?", "?", marker + " unreachable");
end
end
发现 MJS、Generic、HPCServer 和 MJSComputeCloud 集群
discoverClusters 位于此技能的 scripts/ 文件夹中。首次使用前,请将其添加到路径中:
addpath(fullfile(skillRoot, "scripts")); % skillRoot = directory containing this SKILL.md
随附的 discoverClusters 函数封装了与 MATLAB Cluster Profile Manager UI 使用的相同内部发现基础设施。它会返回一个结构体数组,每个已发现的集群对应一个条目:
clusters = discoverClusters(); % all scopes, 30s timeout
% Other forms:
% discoverClusters(Scope="network", TimeoutSeconds=15)
% discoverClusters(Scope="cloud")
每个条目包含以下字段:Type、Name、Host、NumWorkers、MatlabRelease、IsCompatible、CorrespondingProfiles 和 Properties(一个按名称索引、包含所有已发现属性的结构体)。对于 Generic 集群,Properties 包含 PluginScriptsLocation、JobStorageLocation、AdditionalProperties 等——即构建集群所需的所有内容。
简要显示发现结果,并指出 IsCompatible == false(发行版不匹配)的情况,以及任何已设置 CorrespondingProfiles 的集群(表示已导入)。
clusters = discoverClusters();
if isempty(clusters)
disp("No clusters discovered.");
return
end
fprintf("Discovered %d clusters:\n", numel(clusters));
for k = 1:numel(clusters)
profileNote = "no profile";
if ~isempty(clusters(k).CorrespondingProfiles)
profileNote = "profile: " + strjoin(string(clusters(k).CorrespondingProfiles), ", ");
end
compatNote = "compatible";
if ~clusters(k).IsCompatible
compatNote = "INCOMPATIBLE (" + clusters(k).MatlabRelease + ")";
end
fprintf(" [%d] %s '%s' on %s — %s, %s\n", ...
k, clusters(k).Type, clusters(k).Name, clusters(k).Host, ...
compatNote, profileNote);
end
不要退而使用特定于平台的 CLI 工具(nodestatus、mjs status)或杜撰的 API(parallel.cluster.find、parallel.cluster.discover、findResource)。请使用 discoverClusters——这些替代方案要么不存在,要么会绕过受支持的发现基础设施。
如果 discoverClusters 未返回任何结果,并不意味着用户没有集群——并非每个 Generic 集群都配置了可供发现的 .conf 文件。建议用户联系集群管理员,获取可供导入的 .mlsettings 配置文件。
将发现的 MJS 集群另存为配置文件
发现后,使用 parallel.cluster.MJS(Name=, Host=) 构造 MJS 集群,并调用 saveAsProfile(name)。saveAsProfile 是 void——不要赋值其返回值。
parallel.cluster.MJS(Name=,Host=) 会连接到 MJS 查找服务,以验证集群并获取实时属性——这并不是一种开销很小的对象构造操作。如果集群无法访问,该调用会抛出 "Unable to connect to MATLAB Job Scheduler"。
客户端连接时,MJS 集群可能会在 MATLAB 对话框中提示输入凭据,有两种情况:集群的 SecurityLevel 非零,或集群需要在线许可。用户响应前,对话框会阻塞 parallel.cluster.MJS(...);如果用户关闭对话框但未输入凭据,调用会报错:"Operation aborted because no credentials were entered for user ..."。运行任何会构造 MJS 集群对象的代码前,明确警告用户:"即将连接到 MJS 集群 <Name>——请立即切换到 MATLAB;可能会出现凭据对话框,并且该命令会一直阻塞,直到你响应。"如果未发现 MJS 集群,或当前操作不涉及 MJS 集群,则不要发出此警告——Generic、HPCServer、Local 和 Threads 配置文件不会通过这种方式进行身份验证。
始终先按 Type=="MJS" 过滤发现的集群,再采用此模式——发现结果还会包含 Generic / HPCServer / MJSComputeCloud 条目,而对 Slurm 头节点调用 parallel.cluster.MJS 会产生令人困惑的连接错误。
clusters = discoverClusters(Scope="network");
% Pick the first compatible MJS without an existing profile.
isMJS = string({clusters.Type}) == "MJS";
target = clusters(find(isMJS & [clusters.IsCompatible] & ...
cellfun(@isempty, {clusters.CorrespondingProfiles}), 1));
c = parallel.cluster.MJS(Name=target.Name, Host=target.Host);
c.saveAsProfile(target.Name);
fprintf("Saved profile '%s'\n", target.Name);
调用 saveAsProfile(name) 前,检查 parallel.listProfiles——如果 name 已被占用,请询问用户选择其他名称(例如,加入主机名),而不要静默覆盖或创建重复项。
将发现的 Generic(Slurm/PBS/LSF)集群另存为配置文件
Generic 集群通过基于文件系统的发现机制呈现——管理员会提供描述调度器的 .conf 文件,发现机制会从 matlabroot/toolbox/parallel/user/clusterprofiles、$MATLAB_CLUSTER_PROFILES_LOCATION、$HOME 或 $HOME/Downloads 中找到它。发现条目上的 Properties 结构体包含 parallel.cluster.Generic 对象所需的一切信息。
parallel.cluster.Generic 没有 Name 属性——配置文件名称通过 saveAsProfile 传入。
clusters = discoverClusters();
target = clusters(find(string({clusters.Type}) == "Generic" & ...
[clusters.IsCompatible], 1));
p = target.Properties;
c = parallel.cluster.Generic;
c.NumWorkers = double(p.NumWorkers);
c.JobStorageLocation = char(p.JobStorageLocation);
c.PluginScriptsLocation = char(p.PluginScriptsLocation);
c.ClusterMatlabRoot = char(p.ClusterMatlabRoot);
c.OperatingSystem = char(p.OperatingSystem);
c.HasSharedFilesystem = logical(p.HasSharedFilesystem);
c.RequiresOnlineLicensing = logical(p.RequiresOnlineLicensing);
if isfield(p, 'AdditionalProperties')
apFields = fieldnames(p.AdditionalProperties);
for k = 1:numel(apFields)
c.AdditionalProperties.(apFields{k}) = p.AdditionalProperties.(apFields{k});
end
end
c.saveAsProfile(char(p.Name));
同一模式适用于通过 .conf 发现的任何第三方调度器(Slurm、PBS Pro、LSF、Grid Engine、HTCondor)——Type 始终为 Generic;调度器由 PluginScriptsLocation 的内容标识。
导入共享配置文件、设为默认配置并验证
profileName = parallel.importProfile("team_cluster.mlsettings");
parallel.defaultProfile(profileName);
parallel.validateProfile(profileName);
parallel.importProfile 会返回已导入配置文件的名称。parallel.defaultProfile 带一个参数时会设置默认配置,但不会返回有用内容——不带参数调用 parallel.defaultProfile() 才能读取默认配置。
验证集群(分阶段)
使用 parallel.validateProfile(R2025a+)。它接受 StagesToRun、StagesToSkip、NumWorkersToUse 和 ReportFile 名称-值参数。此函数没有输出参数——验证会打印报告,并在请求时写入 ReportFile。
对于新发现或共享的集群,始终传入 NumWorkersToUse——否则验证会使用全部工作进程运行,这通常不是用户所希望的;而在共享集群上(例如 MJSComputeCloud 或站点 MJS),还会占用其他用户可能正在等待使用的资源。使用整个集群进行验证前,请先向用户确认。
parallel.validateProfile("myProfile", ...
StagesToRun=["parcluster", "job", "parpool"], ...
NumWorkersToUse=4, ...
ReportFile="validation-report.txt");
有效阶段(适用于大多数集群类型):"parcluster"、"job"、"spmd-job"、"pool-job"、"parpool"。具体集合因集群 Type 而异——仅 Threads 的配置文件可验证的阶段较少。
在 R2026a+ 中,也可以通过集群对象使用 validate(cluster) 设置相同选项:
c = parcluster("myProfile");
validate(c, StagesToRun=["parcluster", "job", "parpool"]);
对于低于 R2025a 的版本,没有可编写脚本调用的验证 API——请引导用户使用集群配置文件管理器 UI(Home > Parallel > Create and Manage Clusters),并说明该版本限制。
删除配置文件
删除前务必先向用户确认——parallel.deleteProfile 不可撤销。先列出配置文件,并向用户复述要删除的目标。
parallel.deleteProfile("oldCluster");
对于 R2026a 之前的版本,没有可用的公共函数。请引导用户使用 Cluster Profile Manager UI(Home > Parallel > Create and Manage Clusters 或 parallel.gui.ProfileManager.start)。
约定
- 务必在修改前读取配置文件列表:使用
parallel.listProfiles查看现有配置文件,然后调用parallel.defaultProfile()(不带参数)查看默认配置文件。 - 务必在将发现的集群保存为配置文件之前验证
IsCompatible——版本不匹配会导致提交作业失败,而非创建配置文件失败。 - 务必使用
cluster.Type识别集群类型——绝不要使用class(c)。 - 务必在遍历配置文件时,用
try/catch包装parcluster(name)——对于 MJS 配置文件,它会执行网络往返;如果服务器无法访问或版本不匹配,就会失败。 - 务必使用
strcmp(或两个string)比较配置文件名称,而不要使用==。parallel.listProfiles返回char元素组成的元胞数组,而两个长度不同的char数组之间使用==会报错。 - 务必在验证刚发现或共享的集群时,将
NumWorkersToUse限制为较小的数值(例如 2),或先向用户确认工作进程数量——如果不设置,验证会使用集群的全部工作进程。 - 务必在删除配置文件前向用户确认——
parallel.deleteProfile不可撤销。 - 务必在调用
saveAsProfile(name)前检查parallel.listProfiles。如果name已被占用,请向用户询问其他名称,而不要覆盖或创建重复配置文件。 - 优先使用
parallel.listProfiles,而不是已弃用的parallel.clusterProfiles。 - 优先使用
parallel.defaultProfile,而不是已弃用的parallel.defaultClusterProfile。 - 优先使用
parallel.validateProfile(R2025a+)——它不需要先构造集群对象。validate(cluster)提供相同的选项,但直到 R2026a 才推出;在 R2025a 中,请使用独立函数或 GUI。
常见错误
| 错误 | 为什么不对 | 正确做法 |
|---|---|---|
parallel.clusterProfiles | 自 R2022b 起已弃用(仍可使用,但不推荐)。 | parallel.listProfiles |
parallel.defaultClusterProfile(name) | 自 R2022b 起已弃用。 | parallel.defaultProfile(name) |
使用 class(c) 识别集群类型 | 返回 MATLAB 类名称('parallel.cluster.Local'),而不是配置文件类型。 | c.Type(返回 "Local"、"MJS" 等) |
parallel.cluster.find、parallel.cluster.discover、findResource | 这些函数都不存在。 | discoverClusters(随此技能打包提供) |
通过 system() 调用 nodestatus | 这是 CLI 工具,依赖平台,不受 API 支持。 | discoverClusters |
parallel.cluster.removeProfile、parallel.removeProfile | 虚构的名称——这两个函数都不存在。 | parallel.deleteProfile(R2026a+) |
[ok, msg] = validate(c) | validate 没有输出参数。 | 调用 validate(c)(或 parallel.validateProfile),并检查打印出的报告或 ReportFile。 |
name = c.saveAsProfile(name) | saveAsProfile 不返回值——没有输出参数。 | 调用 c.saveAsProfile(name),不要赋值。 |
在 parallel.cluster.Generic 上设置 c.Name | Generic 没有 Name 属性——保存配置文件时才会设置 Name。 | 配置属性,然后调用 c.saveAsProfile("<name>")。 |
对 Threads 配置文件调用 parcluster | parcluster 无法返回 Threads 配置文件。 | 遍历配置文件时跳过 Threads。 |
脚本
scripts/discoverClusters.p— 使用与 Cluster Profile Manager UI 相同的基础设施发现集群。返回一个结构体数组,包含Type、Name、Host、NumWorkers、MatlabRelease、IsCompatible、CorrespondingProfiles。名称-值选项:Scope("all"/"network"/"cloud",默认值为"all")、TimeoutSeconds(默认值为 30)。
Copyright 2026 The MathWorks, Inc.