Skip to content

stablediffusion-ggml: replace hand-maintained enum string arrays with upstream API calls#9192

Merged
mudler merged 2 commits into
masterfrom
copilot/fix-static-assert-errors
Mar 31, 2026
Merged

stablediffusion-ggml: replace hand-maintained enum string arrays with upstream API calls#9192
mudler merged 2 commits into
masterfrom
copilot/fix-static-assert-errors

Conversation

Copilot AI commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

gosd.cpp maintained 6 local string arrays mirroring enums from leejet/stable-diffusion.cpp, each guarded by a static_assert. Every upstream enum addition (e.g. SD_TYPE_NVFP4 bumping SD_TYPE_COUNT 40→41) breaks the build at compile time.

The upstream library already exposes all needed conversions in its public C API — use those instead.

Changes

  • gosd.cpp: Delete all 6 hand-maintained arrays (sample_method_str, schedulers, rng_type_str, prediction_str, lora_apply_mode_str, sd_type_str) and their static_asserts (~100 lines). Replace all usages with upstream API calls:
// Before — breaks on every upstream enum addition:
for (int m = 0; m < SD_TYPE_COUNT; m++) {
    if (sd_type_str[m] && !strcmp(optval, sd_type_str[m])) { found = m; break; }
}

// After — always in sync with upstream:
sd_type_t parsed = str_to_sd_type(optval);
if (parsed != SD_TYPE_COUNT) { wtype = parsed; }

Enum→string lookups likewise replaced: sample_method_str[x]sd_sample_method_name((sample_method_t)x), schedulers[x]sd_scheduler_name((scheduler_t)x).

  • Makefile: Bump STABLEDIFFUSION_GGML_VERSION to 1d6cb0f8c33ddadf1bff8aff40ec2e5b1ccb4940 (the commit that introduced SD_TYPE_NVFP4).

After this change, future upstream enum additions will never break the LocalAI build.

Original prompt

Problem

In backend/go/stablediffusion-ggml/gosd.cpp, there are 6 hand-maintained string arrays that mirror enums from the upstream leejet/stable-diffusion.cpp library, each guarded by a static_assert:

  • sample_method_str[] with static_assert(std::size(sample_method_str) == SAMPLE_METHOD_COUNT)
  • schedulers[] with static_assert(std::size(schedulers) == SCHEDULER_COUNT)
  • rng_type_str[] with static_assert(std::size(rng_type_str) == RNG_TYPE_COUNT)
  • prediction_str[] with static_assert(std::size(prediction_str) == PREDICTION_COUNT)
  • lora_apply_mode_str[] with static_assert(std::size(lora_apply_mode_str) == LORA_APPLY_MODE_COUNT)
  • sd_type_str[] with static_assert(std::size(sd_type_str) == SD_TYPE_COUNT)

Every time upstream adds a new enum value (e.g. SD_TYPE_NVFP4 = 40 bumping SD_TYPE_COUNT from 40→41), these static_asserts fail and the build breaks. This just happened in PR #9188.

Solution

The upstream stable-diffusion.cpp library already exposes all the necessary enum↔string conversion functions in its public C API (include/stable-diffusion.h):

Enum Name → String String → Enum
sd_type_t sd_type_name() str_to_sd_type()
sample_method_t sd_sample_method_name() str_to_sample_method()
scheduler_t sd_scheduler_name() str_to_scheduler()
rng_type_t sd_rng_type_name() str_to_rng_type()
prediction_t sd_prediction_name() str_to_prediction()
lora_apply_mode_t sd_lora_apply_mode_name() str_to_lora_apply_mode()

Required Changes

1. Update backend/go/stablediffusion-ggml/gosd.cpp

Delete all 6 hand-maintained string arrays and their static_asserts (approximately lines 31–130 in gosd.cpp).

Replace all string-to-enum lookups that iterate over the local arrays with calls to the upstream str_to_*() functions. For example:

// BEFORE (breaks when enums change):
for (int m = 0; m < SD_TYPE_COUNT; m++) {
    if (sd_type_str[m] && !strcmp(optval, sd_type_str[m])) {
        found = m;
        break;
    }
}

// AFTER (always in sync with upstream):
sd_type_t parsed = str_to_sd_type(optval);
// str_to_sd_type returns SD_TYPE_COUNT if not found

Replace all enum-to-string lookups like sample_method_str[idx] with calls to the upstream sd_*_name() functions:

// BEFORE:
fprintf(stderr, "Found sampler: %s\n", sample_method_str[sample_method_found]);

// AFTER:
fprintf(stderr, "Found sampler: %s\n", sd_sample_method_name((sample_method_t)sample_method_found));

Apply the same pattern for all 6 enum types:

  • sample_method_str[x]sd_sample_method_name((sample_method_t)x)
  • schedulers[x]sd_scheduler_name((scheduler_t)x)
  • rng_type_str[x]sd_rng_type_name((rng_type_t)x)
  • prediction_str[x]sd_prediction_name((prediction_t)x)
  • lora_apply_mode_str[x]sd_lora_apply_mode_name((lora_apply_mode_t)x)
  • sd_type_str[x]sd_type_name((sd_type_t)x)

For string-to-enum:

  • Loops over sample_method_strstr_to_sample_method(str) (returns SAMPLE_METHOD_COUNT if not found)
  • Loops over schedulersstr_to_scheduler(str) (returns SCHEDULER_COUNT if not found)
  • Loops over rng_type_strstr_to_rng_type(str) (returns RNG_TYPE_COUNT if not found)
  • Loops over prediction_strstr_to_prediction(str) (returns PREDICTION_COUNT if not found)
  • Loops over lora_apply_mode_strstr_to_lora_apply_mode(str) (returns LORA_APPLY_MODE_COUNT if not found)
  • Loops over sd_type_strstr_to_sd_type(str) (returns SD_TYPE_COUNT if not found)

Make sure to carefully preserve all the existing logic and behavior — just remove the local arrays and use the upstream functions instead. The *_COUNT sentinel values returned on failure are the same sentinel values the current code uses.

2. Bump the stable-diffusion.cpp submodule version in the Makefile

In backend/go/stablediffusion-ggml/Makefile, update:

STABLEDIFFUSION_GGML_VERSION?=1d6cb0f8c33ddadf1bff8aff40ec2e5b1ccb4940

This ensures the submodule is at the version that includes SD_TYPE_NVFP4 and the sd_type_name() / str_to_sd_type() functions.

Result

After this change, gosd.cpp will have zero local enum string arrays and will always stay in sync with upstream automatically. Future bumps of the stable-diffusion.cpp submodule will never break the build due to added enum values.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: check the failure in the PR and the upstream changes that broke it

Assistant:

Let me investigate the PR failure and the upstream changes that caused it.

Assistant: Now let me look at the LocalAI code that consumes the upstream library to identify how the breaking changes affect it:

Assistant: Here's my analysis of the PR and the upstream breaking changes:

PR Summary

[PR #9188](https://github.com/mudler/LocalAI/pul...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Fix static assert errors for string arrays in gosd.cpp stablediffusion-ggml: replace hand-maintained enum string arrays with upstream API calls Mar 31, 2026
Copilot AI requested a review from mudler March 31, 2026 09:54
@mudler mudler marked this pull request as ready for review March 31, 2026 10:37
@mudler mudler merged commit 87a6331 into master Mar 31, 2026
42 checks passed
@mudler mudler deleted the copilot/fix-static-assert-errors branch March 31, 2026 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants