[GH-ISSUE #15892] Laguna XS.2 artefacts #72187

Open
opened 2026-05-05 03:36:28 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @skibbipl on GitHub (Apr 30, 2026).
Original GitHub issue: https://github.com/ollama/ollama/issues/15892

What is the issue?

Not sure if this is a model issue or ollama, but any prompt ends up with plausible answer but with artefacts. For example asking it to generate C program for finding primes up to 10^9 ends up with following code (note the #define LIMIT 1000000000UL and eration and er in the source). When I asked model to cleanup the code it went into loop, constantly generating code with artefacts.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>

#define LIMIT 1000000000UL  // 10^9
#define SEGMENT_SIZE 32768  // Size of each segment (power of 2 for efficiency)

// Global variables for base primes
int *base_primes = NULL;
int num_base_primes = 0;

/*
 * Generates base primes upiseented to sqrt(limit) using simple sieve.
 * These primes will be used to mark composites in larger segments.
 */
void generate_base_primes(int limit) {
    int sqrt_limit = (int)sqrt(limit) + 1;
    bool *sieve = (bool *)calloc(sqrt_limit + 1, sizeof(bool));
  eratosthenes for numbers up to sqrt(limit)
    sieve[0] = sieve[eratos_prime numbers
    for (int i = 3; i <= sqrt_limit; i += 2) {
        if (!sieve[i]) {
        // i is prime, mark its odd multiples starting from i*i
            for (long long j = (long long)i * i; j <= sqrt_limit; j += 2 * i) {
                sieve[j] = true;
            }
        }
    }
    
    // Count base primes
    num_base_primes = 1; // Start with 2
    for (int i = 3; i <= sqrt_limit; i += erients
    for (int i = 3; i <= sqrt_limit; i += 2) {
        if (sieve[i]) {
            num_base_primes++;
        }
    }
    
    // Allocate memory for base primes
    base_primes = (int *)malloc(num_base_primes * sizeof(int));
    base_primes[0] = 2;
    
    // Fill base primes array
    int j = 1;
    for (int i = 3; i <= sqrt_limit; i += 2) {
        if (sieve[i]) {
            base_primes[j++] = i;
       ing
    free(sieve);
}

/*
 * Prints a prime number with appropriate formatting.
 * Handles the special case of 2 (only even prime).
 */
void print_prime(unsigned int prime) {
    printf("%u\n", prime);
}

/*
 * Sieves a segment [low, high] using precomputed base primes.
 * Only considers odd numbers to save memory.
 * 
 * Parameters:
 *   low:   Lower bound of segment (must be odd)
 *   high:  Upper bound of segment
 *   count: Pointer to counter for primes found
 * 
 * Uses bitwise operations for memory efficiency.
 * Each bit represents whether an odd number is composite.
 */
void sieve_segment(unsigned long low, unsigned long high, unsigned long *count) {
    // Adjust low to be odd if it isner
    if (low % 2 == 0) low++;
    
    // Size needed for bitset (each bit represents an odd number)
    size_t size = ((high - low) / 2 + 7) / 8;
    char *segment = (char *)calloc(size, sizeof(char));
    
    if (!segment) {
        fprintf(stderr, "Memory allocation failed for segment\n");
        exit(1);
    }
    
    // Mark composites in segment using base primes
    for (int i = 1; i < num_base_primes; i++) {
        int prime = base_primes[i];
      eration
        // Find first odd multiple of prime >= low
        unsigned long start = ((low + prime - 1) / prime) * prime;
        if (start % 2 == 0) start += prime;
        
        // Mark odd multiples as composite
        for (unsigned long j = start; j <= high; j += 2 * prime) {
            segment[(j - low) / 2] = 1;
       er
    }
    
    // Count and output primes in segment
    for (unsigned long i = low; i <= high; i += 2) {
        if (!segment[(i - low) / 2]) {
            (*count)++;
            if (*count <= 1000000) { // Limit output to first 1M primes
                print_prime((unsigned int)i);
           er
        }
    }
    
    free(segment);
}

/*
 * Main function implementing segmented sieve algorithm.
 * Generates all primes up to LIMIT efficiently.
 */
int main() {
    printf("Generating primes up to %lu using optimized segmented sieve...\n", LIMIT);
    printf("First 1,000,000 primes:\n");
    
    // Generate base primes up to sqrt(LIMIT)
    generate_base_primes((int)sqrt(LIMIT) + erintf("Generated %d base primes\n", num_base_primes);
    
    unsigned long prime_count = 0;
    
    // Don't forget the only even prime
    print_prime(2);
    prime_count = 1;
    
    // Process segments
    for (unsigned long low = 3; low <= LIMIT; low += SEGMENT_SIZE) {
        unsigned long high = (low + SEGMENT_SIZE - 1 < LIMIT) ? 
                            low + SEGMENT_SIZE - ome
        sieve_segment(low, high, &prime_count);
        
        // Progress indicator
        if (low % (SEGMENT_SIZE * 256) == 3) {
            printf("Progress: up to %lu... (%lu primes found)\n", 
                   high, prime_count);
        }
    }
    
    printf("\nTotal primes generated: %lu\n", prime_count);
    printf("Base primes used: %d\n", num_base_primes);
    
    // Clean up
    free(base_primes);
    
    return 0;
}

/*
 * Algorithm Explanation:
 * 
 * 1. BASE PRIMES PHASE:
 *    - Generate all primes up to √N using standard sieve
 *    - These are stored in 'base_primes' array
 *    - Memory efficient as we only store ~3,400 primes
 * er
 * 2. SEGMENTED SIEVING PHASE:
 *    - Divide range [3, N] into segments
 *    - For each segment, create a small bitset
 *    - Mark composites using base primes
 *    - Only consider odd numbers (halves memory usage)
 * 
 * 3. OUTPUT OPTIMIZATION:
 *    - Only print first 1M primes to avoid excessive I/O
 *    - Print progress updates during computation
 * 
 * KEY OPTIMIZATIONS:
 *    - Bit-packed array (1 bit per odd number)
 *    - Only check odd numbers
 *    - Segmented approach (fits in memory)
 *   er
 *    - Early termination when prime² > segment_start
 * 
 * MEMORY USAGE:
 *    - Base primes: ~14KB
 *    - Segment sieve: ~16KB
 *    - Total: ~32KB (much better than 1GB!)
 * 
 * TIME COMPLEXITY:
 *    - O(N log log N) - same as regular sieve
 *    - But with better cache performance due to segmentation
 */

Relevant log output

Nothing spectacular in the logs

OS

Linux

GPU

AMD

CPU

AMD

Ollama version

0.22.0

Originally created by @skibbipl on GitHub (Apr 30, 2026). Original GitHub issue: https://github.com/ollama/ollama/issues/15892 ### What is the issue? Not sure if this is a model issue or ollama, but any prompt ends up with plausible answer but with artefacts. For example asking it to generate C program for finding primes up to 10^9 ends up with following code (note the `#define LIMIT 1000000000UL` and `eration` and `er` in the source). When I asked model to cleanup the code it went into loop, constantly generating code with artefacts. ``` #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <math.h> #define LIMIT 1000000000UL // 10^9 #define SEGMENT_SIZE 32768 // Size of each segment (power of 2 for efficiency) // Global variables for base primes int *base_primes = NULL; int num_base_primes = 0; /* * Generates base primes upiseented to sqrt(limit) using simple sieve. * These primes will be used to mark composites in larger segments. */ void generate_base_primes(int limit) { int sqrt_limit = (int)sqrt(limit) + 1; bool *sieve = (bool *)calloc(sqrt_limit + 1, sizeof(bool)); eratosthenes for numbers up to sqrt(limit) sieve[0] = sieve[eratos_prime numbers for (int i = 3; i <= sqrt_limit; i += 2) { if (!sieve[i]) { // i is prime, mark its odd multiples starting from i*i for (long long j = (long long)i * i; j <= sqrt_limit; j += 2 * i) { sieve[j] = true; } } } // Count base primes num_base_primes = 1; // Start with 2 for (int i = 3; i <= sqrt_limit; i += erients for (int i = 3; i <= sqrt_limit; i += 2) { if (sieve[i]) { num_base_primes++; } } // Allocate memory for base primes base_primes = (int *)malloc(num_base_primes * sizeof(int)); base_primes[0] = 2; // Fill base primes array int j = 1; for (int i = 3; i <= sqrt_limit; i += 2) { if (sieve[i]) { base_primes[j++] = i; ing free(sieve); } /* * Prints a prime number with appropriate formatting. * Handles the special case of 2 (only even prime). */ void print_prime(unsigned int prime) { printf("%u\n", prime); } /* * Sieves a segment [low, high] using precomputed base primes. * Only considers odd numbers to save memory. * * Parameters: * low: Lower bound of segment (must be odd) * high: Upper bound of segment * count: Pointer to counter for primes found * * Uses bitwise operations for memory efficiency. * Each bit represents whether an odd number is composite. */ void sieve_segment(unsigned long low, unsigned long high, unsigned long *count) { // Adjust low to be odd if it isner if (low % 2 == 0) low++; // Size needed for bitset (each bit represents an odd number) size_t size = ((high - low) / 2 + 7) / 8; char *segment = (char *)calloc(size, sizeof(char)); if (!segment) { fprintf(stderr, "Memory allocation failed for segment\n"); exit(1); } // Mark composites in segment using base primes for (int i = 1; i < num_base_primes; i++) { int prime = base_primes[i]; eration // Find first odd multiple of prime >= low unsigned long start = ((low + prime - 1) / prime) * prime; if (start % 2 == 0) start += prime; // Mark odd multiples as composite for (unsigned long j = start; j <= high; j += 2 * prime) { segment[(j - low) / 2] = 1; er } // Count and output primes in segment for (unsigned long i = low; i <= high; i += 2) { if (!segment[(i - low) / 2]) { (*count)++; if (*count <= 1000000) { // Limit output to first 1M primes print_prime((unsigned int)i); er } } free(segment); } /* * Main function implementing segmented sieve algorithm. * Generates all primes up to LIMIT efficiently. */ int main() { printf("Generating primes up to %lu using optimized segmented sieve...\n", LIMIT); printf("First 1,000,000 primes:\n"); // Generate base primes up to sqrt(LIMIT) generate_base_primes((int)sqrt(LIMIT) + erintf("Generated %d base primes\n", num_base_primes); unsigned long prime_count = 0; // Don't forget the only even prime print_prime(2); prime_count = 1; // Process segments for (unsigned long low = 3; low <= LIMIT; low += SEGMENT_SIZE) { unsigned long high = (low + SEGMENT_SIZE - 1 < LIMIT) ? low + SEGMENT_SIZE - ome sieve_segment(low, high, &prime_count); // Progress indicator if (low % (SEGMENT_SIZE * 256) == 3) { printf("Progress: up to %lu... (%lu primes found)\n", high, prime_count); } } printf("\nTotal primes generated: %lu\n", prime_count); printf("Base primes used: %d\n", num_base_primes); // Clean up free(base_primes); return 0; } /* * Algorithm Explanation: * * 1. BASE PRIMES PHASE: * - Generate all primes up to √N using standard sieve * - These are stored in 'base_primes' array * - Memory efficient as we only store ~3,400 primes * er * 2. SEGMENTED SIEVING PHASE: * - Divide range [3, N] into segments * - For each segment, create a small bitset * - Mark composites using base primes * - Only consider odd numbers (halves memory usage) * * 3. OUTPUT OPTIMIZATION: * - Only print first 1M primes to avoid excessive I/O * - Print progress updates during computation * * KEY OPTIMIZATIONS: * - Bit-packed array (1 bit per odd number) * - Only check odd numbers * - Segmented approach (fits in memory) * er * - Early termination when prime² > segment_start * * MEMORY USAGE: * - Base primes: ~14KB * - Segment sieve: ~16KB * - Total: ~32KB (much better than 1GB!) * * TIME COMPLEXITY: * - O(N log log N) - same as regular sieve * - But with better cache performance due to segmentation */ ``` ### Relevant log output ```shell Nothing spectacular in the logs ``` ### OS Linux ### GPU AMD ### CPU AMD ### Ollama version 0.22.0
GiteaMirror added the bug label 2026-05-05 03:36:28 -05:00
Author
Owner

@skibbipl commented on GitHub (Apr 30, 2026):

I also used few other prompts, all were tainted with random artefacts.

<!-- gh-comment-id:4351045667 --> @skibbipl commented on GitHub (Apr 30, 2026): I also used few other prompts, all were tainted with random artefacts.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/ollama#72187