Skip to content

Commit 1a31edc

Browse files
authored
Merge pull request LykosAI#1146 from ionite34/dev-to-main
Dev to main
2 parents 26c8f83 + d9ad7df commit 1a31edc

File tree

9 files changed

+228
-237
lines changed

9 files changed

+228
-237
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ All notable changes to Stability Matrix will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).
77

8+
## v2.15.1
9+
### Changed
10+
- Upgraded ComfyUI-Zluda and Stable Diffusion WebUI AMDGPU Forge packages to install and use HIP SDK 6.4.2
11+
### Fixed
12+
- Fixed [#1372](https://github.com/LykosAI/StabilityMatrix/issues/1372) - LiteAsyncException upon starting Stability Matrix v2.15.0
13+
- Fixed [#1391](https://github.com/LykosAI/StabilityMatrix/issues/1391) - "Failed to parse" error when upgrading pip packages with extra index url
14+
- Fixed "cannot access local variable 'job' where it is not associated with a value" error when running jobs in AI Toolkit
15+
- Fixed Civitai browser not always returning at least 30 results when possible on initial search
16+
817
## v2.15.0
918
### Added
1019
- Added new package - [AI Toolkit](https://github.com/ostris/ai-toolkit/)

StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ IPyInstallationManager pyInstallationManager
4545
private const string CppBuildToolsUrl = "https://aka.ms/vs/17/release/vs_BuildTools.exe";
4646

4747
private const string HipSdkDownloadUrl =
48-
"https://download.amd.com/developer/eula/rocm-hub/AMD-Software-PRO-Edition-24.Q4-Win10-Win11-For-HIP.exe";
48+
"https://download.amd.com/developer/eula/rocm-hub/AMD-Software-PRO-Edition-25.Q3-Win10-Win11-For-HIP.exe";
4949
private const string PythonLibsDownloadUrl = "https://cdn.lykos.ai/python_libs_for_sage.zip";
5050

5151
private const string UvWindowsDownloadUrl =
@@ -110,7 +110,7 @@ private string GetPythonLibraryZipPath(PyVersion version) =>
110110
private string HipSdkDownloadPath => Path.Combine(AssetsDir, "AMD-HIP-SDK.exe");
111111

112112
private string HipInstalledPath =>
113-
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "AMD", "ROCm", "6.2");
113+
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "AMD", "ROCm", "6.4");
114114

115115
private string UvDownloadPath => Path.Combine(AssetsDir, "uv.zip");
116116
private string UvExtractPath => Path.Combine(AssetsDir, "uv");
@@ -189,7 +189,7 @@ private async Task<string> RunNode(
189189

190190
result.EnsureSuccessExitCode();
191191
return result.StandardOutput ?? result.StandardError ?? string.Empty;
192-
}
192+
}
193193

194194
public async Task RunNpm(
195195
ProcessArgs args,
@@ -997,15 +997,11 @@ private async Task PatchHipSdkIfNecessary(IProgress<ProgressReport>? progress)
997997

998998
var zipFolderName = downloadUrl switch
999999
{
1000-
_ when downloadUrl.Contains("gfx1201") => null,
1001-
_ when downloadUrl.Contains("gfx1150") => "rocm gfx1150 for hip skd 6.2.4",
1002-
_ when downloadUrl.Contains("gfx1103.AMD") =>
1003-
"rocm gfx1103 AMD 780M phoenix V5.0 for hip skd 6.2.4",
1004-
_ when downloadUrl.Contains("gfx1034") => "rocm gfx1034-gfx1035-gfx1036 for hip sdk 6.2.4",
1005-
_ when downloadUrl.Contains("gfx1032") => "rocm gfx1032 for hip skd 6.2.4(navi21 logic)",
1006-
_ when downloadUrl.Contains("gfx1031") => "rocm gfx1031 for hip skd 6.2.4 (littlewu's logic)",
1007-
_ when downloadUrl.Contains("gfx1010") =>
1008-
"rocm gfx1010-xnack-gfx1011-xnack-gfx1012-xnack- for hip sdk 6.2.4",
1000+
_ when downloadUrl.Contains("gfx1103.for.hip") => "rocm gfx1103 for hip 6.4.2",
1001+
_ when downloadUrl.Contains("gfx1034") => "rocm gfx1034.gfx1035.gfx1036 for hip 6.4.2",
1002+
_ when downloadUrl.Contains("gfx1032") => "rocm gfx1032 for hip 6.4.2",
1003+
_ when downloadUrl.Contains("gfx1031") => "rocm gfx1031 for hip 6.4.2",
1004+
_ when downloadUrl.Contains("gfx1010") => "rocm gfx1010-xnack-gfx1012-xnack-.for.hip6.4.2",
10091005
_ => null,
10101006
};
10111007

@@ -1035,27 +1031,29 @@ _ when downloadUrl.Contains("gfx1010") =>
10351031

10361032
private string? GetDownloadUrlFromGpuName(string name)
10371033
{
1034+
// not used anymore but good to know for gfx -> name reference
10381035
// gfx1201
1039-
if (name.Contains("9060") || name.Contains("9070"))
1040-
{
1041-
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1201.for.hip.skd.6.2.4-no-optimized.7z";
1042-
}
1036+
// if (name.Contains("9060") || name.Contains("9070"))
1037+
// {
1038+
// return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1201.for.hip.skd.6.2.4-no-optimized.7z";
1039+
// }
10431040

1041+
// not used anymore but good to know for gfx -> name reference
10441042
// gfx1150
1045-
if (
1046-
name.Contains("8050S")
1047-
|| name.Contains("8060S")
1048-
|| name.Contains("880M")
1049-
|| name.Contains("890M")
1050-
)
1051-
{
1052-
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1150.for.hip.skd.6.2.4.7z";
1053-
}
1043+
// if (
1044+
// name.Contains("8050S")
1045+
// || name.Contains("8060S")
1046+
// || name.Contains("880M")
1047+
// || name.Contains("890M")
1048+
// )
1049+
// {
1050+
// return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1150.for.hip.skd.6.2.4.7z";
1051+
// }
10541052

10551053
// gfx1103
10561054
if (name.Contains("740M") || name.Contains("760M") || name.Contains("780M") || name.Contains("Z1"))
10571055
{
1058-
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1103.AMD.780M.phoenix.V5.0.for.hip.sdk.6.2.4.7z";
1056+
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1103.for.hip.6.4.2.7z";
10591057
}
10601058

10611059
// gfx1034, gfx1035, gfx1036
@@ -1070,7 +1068,7 @@ _ when downloadUrl.Contains("gfx1010") =>
10701068
|| name.Contains("Graphics 128SP")
10711069
)
10721070
{
1073-
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1034-gfx1035-gfx1036.for.hip.sdk.6.2.4.7z";
1071+
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1034.gfx1035.gfx1036.for.hip.6.4.2.7z";
10741072
}
10751073

10761074
// gfx1032
@@ -1081,7 +1079,7 @@ _ when downloadUrl.Contains("gfx1010") =>
10811079
|| name.Contains("6650")
10821080
)
10831081
{
1084-
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1032.for.hip.sdk.6.2.4.navi21.logic.7z";
1082+
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1032.for.hip.6.4.2.7z";
10851083
}
10861084

10871085
// gfx1031
@@ -1092,13 +1090,13 @@ _ when downloadUrl.Contains("gfx1010") =>
10921090
|| name.Contains("6850M")
10931091
)
10941092
{
1095-
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1031.for.hip.sdk.6.2.4.littlewu.s.logic.7z";
1093+
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1031.for.hip.6.4.2.7z";
10961094
}
10971095

10981096
// gfx1010/1012
10991097
if (name.Contains("5700") || name.Contains("5600") || name.Contains("5300") || name.Contains("5500"))
11001098
{
1101-
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1010-xnack-gfx1011-xnack-gfx1012-xnack-.for.hip.sdk.6.2.4.7z";
1099+
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1010-xnack-gfx1012-xnack-.for.hip6.4.2.7z";
11021100
}
11031101

11041102
return null;

StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CivitAiBrowserViewModel.cs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public sealed partial class CivitAiBrowserViewModel : TabViewModelBase, IInfinit
5252

5353
private readonly SourceCache<OrderedValue<CivitModel>, int> modelCache = new(static ov => ov.Value.Id);
5454

55+
private const int TargetPageItemCount = 30;
56+
5557
[ObservableProperty]
5658
private IObservableCollection<CheckpointBrowserCardViewModel> modelCards =
5759
new ObservableCollectionExtended<CheckpointBrowserCardViewModel>();
@@ -453,8 +455,46 @@ private async Task CivitModelQuery(CivitModelsRequest request, bool isInfiniteSc
453455
}
454456
else
455457
{
456-
modelsResponse = await civitApi.GetModels(request);
457-
models = modelsResponse.Items;
458+
// Auto-paginate via cursor until we fill the target page size or run out
459+
var collectedById = new HashSet<int>();
460+
var targetCount = request.Limit ?? TargetPageItemCount;
461+
var safetyGuard = 0;
462+
463+
while (true)
464+
{
465+
var resp = await civitApi.GetModels(request);
466+
modelsResponse = resp;
467+
468+
if (resp.Items != null)
469+
{
470+
foreach (var item in resp.Items)
471+
{
472+
if (collectedById.Add(item.Id))
473+
{
474+
models.Add(item);
475+
}
476+
}
477+
}
478+
479+
// Check how many items survive local filtering
480+
var filteredCount = models
481+
.Where(m => m.Type.ConvertTo<SharedFolderType>() > 0)
482+
.Count(m => m.Mode == null);
483+
484+
var next = resp.Metadata?.NextCursor;
485+
if (filteredCount >= targetCount || string.IsNullOrEmpty(next))
486+
{
487+
break;
488+
}
489+
490+
request.Cursor = next;
491+
492+
if (++safetyGuard >= 10)
493+
{
494+
// Avoid unbounded looping on unexpected cursors
495+
break;
496+
}
497+
}
458498
}
459499

460500
if (models is null)
@@ -634,6 +674,7 @@ private async Task SearchModels(bool isInfiniteScroll = false)
634674
// Build request
635675
var modelRequest = new CivitModelsRequest
636676
{
677+
Limit = TargetPageItemCount + 20, // Fetch a few extra to account for local filtering
637678
Nsfw = "true", // Handled by local view filter
638679
Sort = SortMode,
639680
Period = SelectedPeriod,

StabilityMatrix.Avalonia/ViewModels/Dialogs/PythonPackagesViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ private async Task UpgradePackageVersion(
239239

240240
if (extraIndexUrl != null)
241241
{
242-
args = args.AddArg(("--extra-index-url", extraIndexUrl));
242+
args = args.AddArgs("--extra-index-url", extraIndexUrl);
243243
}
244244

245245
var steps = new List<IPackageStep>

StabilityMatrix.Avalonia/ViewModels/Inference/ModelCardViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ public override void LoadStateFromJsonObject(JsonObject state)
309309
? HybridModelFile.None
310310
: ClientManager.ClipModels.FirstOrDefault(x => x.RelativePath == model.SelectedClip3Name);
311311

312-
SelectedClip4 = model.SelectedClip3Name is null
312+
SelectedClip4 = model.SelectedClip4Name is null
313313
? HybridModelFile.None
314314
: ClientManager.ClipModels.FirstOrDefault(x => x.RelativePath == model.SelectedClip4Name);
315315

StabilityMatrix.Core/Database/LiteDbContext.cs

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using StabilityMatrix.Core.Models.Api;
1111
using StabilityMatrix.Core.Models.Configs;
1212
using StabilityMatrix.Core.Models.Database;
13+
using StabilityMatrix.Core.Models.FileInterfaces;
1314
using StabilityMatrix.Core.Services;
1415

1516
namespace StabilityMatrix.Core.Database;
@@ -63,18 +64,25 @@ IOptions<DebugOptions> debugOptions
6364

6465
private LiteDatabaseAsync CreateDatabase()
6566
{
66-
LiteDatabaseAsync? db = null;
67+
// Try at most twice:
68+
// - attempt 0: open/repair if needed
69+
// - on "Detected loop in FindAll": dispose, delete file, try once more
70+
const int maxAttempts = 2;
71+
var dbPath = Path.Combine(settingsManager.LibraryDir, "StabilityMatrix.db");
6772

68-
if (debugOptions.TempDatabase)
73+
for (var attempt = 0; attempt < maxAttempts; attempt++)
6974
{
70-
db = new LiteDatabaseAsync(":temp:");
71-
}
72-
else
73-
{
74-
// Attempt to create connection, might be in use
75+
LiteDatabaseAsync? db = null;
76+
7577
try
7678
{
77-
var dbPath = Path.Combine(settingsManager.LibraryDir, "StabilityMatrix.db");
79+
if (debugOptions.TempDatabase)
80+
{
81+
db = new LiteDatabaseAsync(":temp:");
82+
RegisterRefs();
83+
return db;
84+
}
85+
7886
db = new LiteDatabaseAsync(
7987
new ConnectionString { Filename = dbPath, Connection = ConnectionType.Shared }
8088
);
@@ -86,33 +94,73 @@ private LiteDatabaseAsync CreateDatabase()
8694
"Database collation is not Ordinal ({SortOption}), rebuilding...",
8795
sortOption
8896
);
89-
9097
var options = new RebuildOptions
9198
{
9299
Collation = new Collation(CultureInfo.InvariantCulture.LCID, CompareOptions.Ordinal),
93100
};
94-
95101
db.RebuildAsync(options).GetAwaiter().GetResult();
96102
}
103+
104+
RegisterRefs();
105+
return db;
97106
}
98-
catch (IOException e)
107+
catch (LiteAsyncException ex)
108+
when (ex.InnerException is LiteException e
109+
&& e.Message.Contains("Detected loop in FindAll", StringComparison.OrdinalIgnoreCase)
110+
)
111+
{
112+
logger.LogWarning("Database corruption detected ({Message}), rebuilding...", e.Message);
113+
114+
try
115+
{
116+
db?.Dispose();
117+
}
118+
catch
119+
{
120+
// ignored
121+
}
122+
123+
try
124+
{
125+
// Backup then delete, in case we want to inspect later.
126+
var corruptPath = dbPath + ".old-" + DateTime.UtcNow.ToString("yyyyMMddHHmmss");
127+
if (File.Exists(dbPath))
128+
{
129+
File.Copy(dbPath, corruptPath, overwrite: false);
130+
File.Delete(dbPath);
131+
}
132+
}
133+
catch (Exception delEx)
134+
{
135+
logger.LogWarning("Failed to delete corrupt DB: {Message}", delEx.Message);
136+
// If we can't delete, no point retrying; break to fallback.
137+
break;
138+
}
139+
}
140+
catch (IOException ioEx)
99141
{
100142
logger.LogWarning(
101143
"Database in use or not accessible ({Message}), using temporary database",
102-
e.Message
144+
ioEx.Message
103145
);
146+
break; // fall through to temp
104147
}
105148
}
106149

107150
// Fallback to temporary database
108-
db ??= new LiteDatabaseAsync(":temp:");
109-
110-
// Register reference fields
111-
LiteDBExtensions.Register<CivitModel, CivitModelVersion>(m => m.ModelVersions, "CivitModelVersions");
112-
LiteDBExtensions.Register<CivitModelQueryCacheEntry, CivitModel>(e => e.Items, "CivitModels");
113-
LiteDBExtensions.Register<LocalModelFile, CivitModel>(e => e.LatestModelInfo, "CivitModels");
151+
var tempDb = new LiteDatabaseAsync(":temp:");
152+
RegisterRefs();
153+
return tempDb;
114154

115-
return db;
155+
void RegisterRefs()
156+
{
157+
LiteDBExtensions.Register<CivitModel, CivitModelVersion>(
158+
m => m.ModelVersions,
159+
"CivitModelVersions"
160+
);
161+
LiteDBExtensions.Register<CivitModelQueryCacheEntry, CivitModel>(e => e.Items, "CivitModels");
162+
LiteDBExtensions.Register<LocalModelFile, CivitModel>(e => e.LatestModelInfo, "CivitModels");
163+
}
116164
}
117165

118166
public async Task<(CivitModel?, CivitModelVersion?)> FindCivitModelFromFileHashAsync(string hashBlake3)

StabilityMatrix.Core/Models/Packages/AiToolkit.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ await npmProcess
183183

184184
private ImmutableDictionary<string, string> GetEnvVars(ImmutableDictionary<string, string> env)
185185
{
186+
// set SETUPTOOLS_USE_DISTUTILS=setuptools to avoid job errors
187+
env = env.SetItem("SETUPTOOLS_USE_DISTUTILS", "setuptools");
188+
186189
var pathBuilder = new EnvPathBuilder();
187190

188191
if (env.TryGetValue("PATH", out var value))

0 commit comments

Comments
 (0)