exaloop / codon

A high-performance, zero-overhead, extensible Python compiler using LLVM
https://docs.exaloop.io/codon
Other
15.14k stars 520 forks source link

Segmentation dump in release mode #127

Open rHermes opened 1 year ago

rHermes commented 1 year ago

Hey!

I've been trying to solve a problem in AoC with codon and it's been working fine, but I tried turning on release mode and I get an exception then:

import re
# import collections as cs

# import typing

TN = 32
# TN = 24

ncombos = 3

@tuple
class Blueprint():
    id: int
    ore_robot_ore_cost: int
    clay_robot_ore_cost: int
    ob_robot_ore_cost: int
    ob_robot_clay_cost: int
    geo_robot_ore_cost: int
    geo_robot_ob_cost: int

@tuple
class GameState:
    blueprint: Blueprint

    ore: int = 0
    clay: int = 0
    ob: int = 0

    # incoming_ore_robots: int = 0
    # incoming_clay_robots: int = 0
    # incoming_ob_robots: int = 0

    ore_robots: int = 1
    clay_robots: int = 0
    ob_robots: int = 0
    geo_robots: int = 0

    time : int = 0

    def sig(self) -> int:
        return hash((self.time, self.ore, self.clay, self.ob, self.ore_robots, self.clay_robots, self.ob_robots, self.geo_robots))

def get_blueprints(filename: str) -> List[Blueprint]:
    with open(filename) as f:
        blueprints: list[Blueprint] = []
        for line in f:
            id, a, b, c, d, e, h = list(map(int, re.findall("-?[0-9]+", line)))
            blueprints.append(Blueprint(id, a, b, c, d, e, h))

        return blueprints

def get_calculated(filename: str) -> dict[int,int]:
    ans = {}
    with open(filename) as f:
        for line in f:
            a, b = line.rstrip().split(" ")
            ans[int(a)] = int(b)

    return ans

# Returns the maximum number of geos you can get. We assume here that we can only build one
# robot each round.
min_time = 10000
best_thing: dict[int, int]
def best_possible(cache: dict[int, int], state: GameState, avoidOre: bool, avoidClay: bool, avoidOb: bool, avoidGeo: bool) -> int:
    global min_time

    if TN <= state.time:
        return 0

    if state.time == TN-1:
        return state.geo_robots

    if avoidOre and avoidClay and avoidOb and avoidGeo:
        return (TN - state.time) * state.geo_robots

    if state.time == TN-2:
        max_new_geo_ore = state.ore // state.blueprint.geo_robot_ore_cost
        max_new_geo_ob = state.ob // state.blueprint.geo_robot_ob_cost
        max_new_geo = min(max_new_geo_ore, max_new_geo_ob)
        return state.geo_robots*2 + max_new_geo
        # if state.blueprint.geo_robot_ore_cost <= state.ore and state.blueprint.geo_robot_ob_cost <= state.ob:
        #     return state.geo_robots*2 + 1
        # else:
        #     return state.geo_robots*2

    sig = state.sig()
    if sig in cache:
        # print(state)
        return cache[sig]

    ans = 0
    for nGeo in range(ncombos):
        if 0 < nGeo and avoidGeo:
            break

        for nOb in range(ncombos):
            if 0 < nOb and avoidOb:
                break
            for nClay in range(ncombos):
                if 0 < nClay and avoidClay:
                    break
                for nOre in range(ncombos):
                    if 0 < nOre and avoidOre:
                        break

                    ore_cost = nOre * state.blueprint.ore_robot_ore_cost + nClay*state.blueprint.clay_robot_ore_cost + nOb*state.blueprint.ob_robot_ore_cost + nGeo*state.blueprint.geo_robot_ore_cost
                    clay_cost = nOb * state.blueprint.ob_robot_clay_cost
                    ob_cost = nGeo * state.blueprint.geo_robot_ob_cost
                    if state.ore < ore_cost or state.clay < clay_cost or state.ob < ob_cost:
                        break

                    # if (nOre + nOb +nGeo + nClay > 1):
                    #     print("We have multiple buys, ", nOre, nClay, nOb, nGeo)
                    new_avoidOre = state.blueprint.ore_robot_ore_cost <= (state.ore - ore_cost)
                    new_avoidClay = state.blueprint.clay_robot_ore_cost <= (state.ore - ore_cost)
                    new_avoidOb = state.blueprint.ob_robot_ore_cost <= (state.ore - ore_cost) and state.blueprint.ob_robot_clay_cost <= (state.clay - clay_cost)
                    new_avoidGeo = state.blueprint.geo_robot_ore_cost <= (state.ore - ore_cost) and state.blueprint.geo_robot_ob_cost <= (state.ob - ob_cost)

                    # if not (nGeo == 0 and nOre == 0 and nClay == 0 and nOb == 0) and (new_avoidOre or new_avoidOb or new_avoidClay or new_avoidGeo):
                    #     print("we found a nice shortcuit")

                    # We don't do anything
                    nothing_next_turn = GameState(
                            blueprint=state.blueprint,
                            time=state.time+1,

                            ore=state.ore + state.ore_robots - ore_cost,
                            clay=state.clay + state.clay_robots - clay_cost,
                            ob=state.ob + state.ob_robots - ob_cost,

                            ore_robots=state.ore_robots + nOre,
                            clay_robots=state.clay_robots + nClay,
                            ob_robots=state.ob_robots + nOb,
                            geo_robots=state.geo_robots + nGeo,
                            )

                    ans = max(ans, state.geo_robots + best_possible(cache, nothing_next_turn, new_avoidOre, new_avoidClay, new_avoidOb, new_avoidGeo))

    if state.time < min_time:
        min_time = state.time
        print("New min time: ", min_time, ans)

    cache[sig] = ans
    return ans

def calc_quality_level(blueprint: Blueprint) -> int:
    global min_time
    min_time = 10000000000
    cache: dict[int, int] = {}
    state = GameState(blueprint = blueprint)
    score = best_possible(cache, state, False, False, False, False)

    print(blueprint.id, score)
    return score

ans = 0
# blueprints = get_blueprints("example.txt")
# calculated = get_calculated("ncombos-" + str(ncombos) + ".txt")
blueprints = get_blueprints("input.txt")

ans = 1
for blueprint in blueprints[:3]:
    score = calc_quality_level(blueprint)
    ans *= score

print(ans)

The input file is:

Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 4 ore and 11 obsidian.
Blueprint 2: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 2 ore and 12 obsidian.
Blueprint 3: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 2 ore and 10 obsidian.
Blueprint 4: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 2 ore and 15 obsidian.
Blueprint 5: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 4 ore and 20 obsidian.
Blueprint 6: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 19 clay. Each geode robot costs 2 ore and 18 obsidian.
Blueprint 7: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 20 obsidian.
Blueprint 8: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 4 ore and 17 obsidian.
Blueprint 9: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 4 ore and 7 obsidian.
Blueprint 10: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 3 ore and 16 obsidian.
Blueprint 11: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 4 ore and 12 obsidian.
Blueprint 12: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 18 obsidian.
Blueprint 13: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian.
Blueprint 14: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 16 clay. Each geode robot costs 3 ore and 14 obsidian.
Blueprint 15: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 4 ore and 16 obsidian.
Blueprint 16: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 3 ore and 19 obsidian.
Blueprint 17: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 19 obsidian.
Blueprint 18: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 2 ore and 8 obsidian.
Blueprint 19: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 3 ore and 10 obsidian.
Blueprint 20: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 12 obsidian.
Blueprint 21: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 17 obsidian.
Blueprint 22: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 12 obsidian.
Blueprint 23: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 3 ore and 9 obsidian.
Blueprint 24: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 2 ore and 10 obsidian.
Blueprint 25: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 2 ore and 8 obsidian.
Blueprint 26: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 17 obsidian.
Blueprint 27: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 8 obsidian.
Blueprint 28: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 2 ore and 12 obsidian.
Blueprint 29: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 19 clay. Each geode robot costs 3 ore and 13 obsidian.
Blueprint 30: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 6 clay. Each geode robot costs 4 ore and 11 obsidian.

I'm using codon version 0.15.3 on linux amd64. I get a segmentation fault looking like this:

$ codon run --release cod-p1.py
New min time:  29 0
New min time:  28 0
New min time:  27 0
New min time:  26 0
New min time:  25 0
New min time:  24 0
New min time:  23 0
New min time:  22 0
New min time:  21 0
New min time:  20 0
New min time:  19 0
New min time:  18 0
New min time:  17 0
New min time:  16 0
New min time:  15 0
New min time:  14 0
New min time:  13 0
New min time:  12 0
New min time:  11 0
New min time:  10 0
New min time:  9 0
New min time:  8 0
New min time:  7 0
New min time:  6 0
New min time:  5 0
zsh: segmentation fault (core dumped)  codon run --release cod-p1.py

The output from coredumpctl:

Module libomp.so without build-id.
Module libcodonrt.so without build-id.
Module libcodonc.so without build-id.
Module codon without build-id.
Stack trace of thread 160876:
#0  0x00007fe45850b347 GC_mark_from (libcodonrt.so + 0xf0347)
#1  0x00007fe45850beed n/a (libcodonrt.so + 0xf0eed)
#2  0x00007fe45850a672 GC_mark_some (libcodonrt.so + 0xef672)
#3  0x00007fe45850029d n/a (libcodonrt.so + 0xe529d)
#4  0x00007fe458500069 GC_try_to_collect_inner (libcodonrt.so + 0xe5069)
#5  0x00007fe4585014a0 GC_collect_or_expand (libcodonrt.so + 0xe64a0)
#6  0x00007fe4585119bb GC_alloc_large (libcodonrt.so + 0xf69bb)
#7  0x00007fe458512007 GC_generic_malloc (libcodonrt.so + 0xf7007)
#8  0x00007fe458512181 GC_malloc_kind_global (libcodonrt.so + 0xf7181)
#9  0x00007fe45851417d GC_realloc (libcodonrt.so + 0xf917d)
#10 0x00007fe458c1406e n/a (n/a + 0x0)
ELF object binary architecture: AMD x86-64
arshajii commented 1 year ago

Thanks for the report -- this is probably some OOM issue, since when I run it it just keeps using more and more memory (in both release and debug; killed after >30GB). Are you able to run it to completion in non-release mode?

rHermes commented 1 year ago

I don't remember with this program, but I had the same type of problem with a program that did complete in debug mode. I'll try to remake the example that completed

rHermes commented 1 year ago

@arshajii, hey!

It is not the exact same program, don't have it anymore, but a different version. This gets a segmentation fault in release mode for me, but completes in debug mode:

import re
# import collections as cs
import math

# import typing

@tuple
class Blueprint():
    id: int
    ore_robot_ore_cost: int
    clay_robot_ore_cost: int
    ob_robot_ore_cost: int
    ob_robot_clay_cost: int
    geo_robot_ore_cost: int
    geo_robot_ob_cost: int

@tuple
class GameState:
    blueprint: Blueprint

    ore: int = 0
    clay: int = 0
    ob: int = 0

    # incoming_ore_robots: int = 0
    # incoming_clay_robots: int = 0
    # incoming_ob_robots: int = 0

    ore_robots: int = 1
    clay_robots: int = 0
    ob_robots: int = 0
    geo_robots: int = 0

    time : int = 0

    def sig(self) -> int:
        return hash((self.time, self.ore, self.clay, self.ob, self.ore_robots, self.clay_robots, self.ob_robots, self.geo_robots))

def get_blueprints(filename: str) -> List[Blueprint]:
    with open(filename) as f:
        blueprints: list[Blueprint] = []
        for line in f:
            id, a, b, c, d, e, h = list(map(int, re.findall("-?[0-9]+", line)))
            blueprints.append(Blueprint(id, a, b, c, d, e, h))

        return blueprints

TN = 32

# Returns the maximum number of geos you can get. We assume here that we can only build one
# robot each round.
def best_possible(cache: dict[int, int], state: GameState) -> int:
    if TN <= state.time:
        return 0

    if state.time == TN-1:
        return state.geo_robots

    sig = state.sig()
    if sig in cache:
        return cache[sig]

    # The minimum we can get is the geo_robots
    ans = (TN-state.time)*state.geo_robots

    # We but an ore robot
    if state.blueprint.ore_robot_ore_cost <= state.ore:
        next_turn = GameState(
                blueprint=state.blueprint,
                time=state.time+1,
                ore=state.ore + state.ore_robots - state.blueprint.ore_robot_ore_cost,
                clay=state.clay + state.clay_robots,
                ob=state.ob + state.ob_robots,
                ore_robots=state.ore_robots + 1,
                clay_robots=state.clay_robots,
                ob_robots=state.ob_robots,
                geo_robots=state.geo_robots,
                )

        ans = max(ans, state.geo_robots + best_possible(cache, next_turn))
    elif 0 < state.ore_robots:
        time_til_enough_ore = int(math.ceil((state.blueprint.ore_robot_ore_cost - state.ore) / state.ore_robots))
        time_spent = time_til_enough_ore + 1
        if time_spent + state.time <= TN:
            next_turn = GameState(
                    blueprint=state.blueprint,
                    time=state.time+time_spent,
                    ore=state.ore + state.ore_robots*time_spent - state.blueprint.ore_robot_ore_cost,
                    clay=state.clay + state.clay_robots*time_spent,
                    ob=state.ob + state.ob_robots*time_spent,
                    ore_robots=state.ore_robots + 1,
                    clay_robots=state.clay_robots,
                    ob_robots=state.ob_robots,
                    geo_robots=state.geo_robots,
                    )

            ans = max(ans, state.geo_robots*time_spent + best_possible(cache, next_turn))

    # We but an clay
    if state.blueprint.clay_robot_ore_cost <= state.ore:
        next_turn = GameState(
                blueprint=state.blueprint,
                time=state.time+1,
                ore=state.ore + state.ore_robots - state.blueprint.clay_robot_ore_cost,
                clay=state.clay + state.clay_robots,
                ob=state.ob + state.ob_robots,
                ore_robots=state.ore_robots,
                clay_robots=state.clay_robots + 1,
                ob_robots=state.ob_robots,
                geo_robots=state.geo_robots,
                )

        ans = max(ans, state.geo_robots + best_possible(cache, next_turn))
    elif 0 < state.ore_robots:
        time_til_enough_ore = int(math.ceil((state.blueprint.clay_robot_ore_cost - state.ore) / state.ore_robots))
        time_spent = time_til_enough_ore + 1
        if time_spent + state.time <= TN:
            next_turn = GameState(
                    blueprint=state.blueprint,
                    time=state.time+time_spent,
                    ore=state.ore + state.ore_robots*time_spent - state.blueprint.clay_robot_ore_cost,
                    clay=state.clay + state.clay_robots*time_spent,
                    ob=state.ob + state.ob_robots*time_spent,
                    ore_robots=state.ore_robots,
                    clay_robots=state.clay_robots + 1,
                    ob_robots=state.ob_robots,
                    geo_robots=state.geo_robots,
                    )

            ans = max(ans, state.geo_robots*time_spent + best_possible(cache, next_turn))

    # We but an ob robot
    if state.blueprint.ob_robot_ore_cost <= state.ore and state.blueprint.ob_robot_clay_cost <= state.clay:
        next_turn = GameState(
                blueprint=state.blueprint,
                time=state.time+1,
                ore=state.ore + state.ore_robots - state.blueprint.ob_robot_ore_cost,
                clay=state.clay + state.clay_robots - state.blueprint.ob_robot_clay_cost,
                ob=state.ob + state.ob_robots,
                ore_robots=state.ore_robots,
                clay_robots=state.clay_robots,
                ob_robots=state.ob_robots + 1,
                geo_robots=state.geo_robots,
                )

        ans = max(ans, state.geo_robots + best_possible(cache, next_turn))
    elif 0 < state.ore_robots and 0 < state.clay_robots:
        time_til_enough_ore = int(math.ceil((state.blueprint.ob_robot_ore_cost - state.ore) / state.ore_robots))
        time_til_enough_clay = int(math.ceil((state.blueprint.ob_robot_clay_cost - state.clay) / state.clay_robots))
        time_spent = max(time_til_enough_ore, time_til_enough_clay) + 1
        if time_spent + state.time <= TN:
            next_turn = GameState(
                    blueprint=state.blueprint,
                    time=state.time+time_spent,
                    ore=state.ore + state.ore_robots*time_spent - state.blueprint.ob_robot_ore_cost,
                    clay=state.clay + state.clay_robots*time_spent - state.blueprint.ob_robot_clay_cost,
                    ob=state.ob + state.ob_robots*time_spent,
                    ore_robots=state.ore_robots,
                    clay_robots=state.clay_robots,
                    ob_robots=state.ob_robots + 1,
                    geo_robots=state.geo_robots,
                    )

            ans = max(ans, state.geo_robots*time_spent + best_possible(cache, next_turn))

    # We but an geo robot
    if state.blueprint.geo_robot_ore_cost <= state.ore and state.blueprint.geo_robot_ob_cost <= state.ob:
        next_turn = GameState(
                blueprint=state.blueprint,
                time=state.time+1,
                ore=state.ore + state.ore_robots - state.blueprint.geo_robot_ore_cost,
                clay=state.clay + state.clay_robots,
                ob=state.ob + state.ob_robots - state.blueprint.geo_robot_ob_cost,
                ore_robots=state.ore_robots,
                clay_robots=state.clay_robots,
                ob_robots=state.ob_robots,
                geo_robots=state.geo_robots+1,
                )

        ans = max(ans, state.geo_robots + best_possible(cache, next_turn))
    elif 0 < state.ore_robots and 0 < state.ob_robots:
        time_til_enough_ore = int(math.ceil((state.blueprint.geo_robot_ore_cost - state.ore) / state.ore_robots))
        time_til_enough_ob = int(math.ceil((state.blueprint.geo_robot_ob_cost - state.ob) / state.ob_robots))
        time_spent = max(time_til_enough_ore, time_til_enough_ob) + 1
        if time_spent + state.time <= TN:
            next_turn = GameState(
                    blueprint=state.blueprint,
                    time=state.time+time_spent,
                    ore=state.ore + state.ore_robots*time_spent - state.blueprint.geo_robot_ore_cost,
                    clay=state.clay + state.clay_robots*time_spent,
                    ob=state.ob + state.ob_robots*time_spent - state.blueprint.geo_robot_ob_cost,
                    ore_robots=state.ore_robots,
                    clay_robots=state.clay_robots,
                    ob_robots=state.ob_robots,
                    geo_robots=state.geo_robots+1,
                    )

            ans = max(ans, state.geo_robots*time_spent + best_possible(cache, next_turn))

    cache[sig] = ans
    return ans

def calc_quality_level(blueprint: Blueprint) -> int:
    cache: dict[int, int] = {}
    state = GameState(blueprint = blueprint)
    score = best_possible(cache, state)

    print(blueprint.id, score)
    return score

ans = 0
# blueprints = get_blueprints("example.txt")
blueprints = get_blueprints("input.txt")

# 1 26 (Also with new version)

# 2 21
# 
# 3 13

# ! 1 28
# ans = 13 * 26
ans = 1
# @par
for blueprint in blueprints[:3]:
    score = calc_quality_level(blueprint)
    # ans += score
    ans *= score

print(ans)

Same input as before. and the coredump in release mode:

                Module libomp.so without build-id.
                Module libcodonrt.so without build-id.
                Module libcodonc.so without build-id.
                Module codon without build-id.
                Stack trace of thread 457297:
                #0  0x00007f50c48c6347 GC_mark_from (libcodonrt.so + 0xf0347)
                #1  0x00007f50c48c6eed n/a (libcodonrt.so + 0xf0eed)
                #2  0x00007f50c48c5672 GC_mark_some (libcodonrt.so + 0xef672)
                #3  0x00007f50c48bb29d n/a (libcodonrt.so + 0xe529d)
                #4  0x00007f50c48bb069 GC_try_to_collect_inner (libcodonrt.so + 0xe5069)
                #5  0x00007f50c48bc4a0 GC_collect_or_expand (libcodonrt.so + 0xe64a0)
                #6  0x00007f50c48cc9bb GC_alloc_large (libcodonrt.so + 0xf69bb)
                #7  0x00007f50c48cd007 GC_generic_malloc (libcodonrt.so + 0xf7007)
                #8  0x00007f50c48cd181 GC_malloc_kind_global (libcodonrt.so + 0xf7181)
                #9  0x00007f50c48cf17d GC_realloc (libcodonrt.so + 0xf917d)
                #10 0x00007f50c4fcf203 n/a (n/a + 0x0)
                ELF object binary architecture: AMD x86-64
arshajii commented 1 year ago

Thanks for the update -- just tried your new program (although on Mac M1) and it ran correctly in both debug and release mode. Are you building Codon yourself? If so what options are you using when building?

inumanag commented 1 year ago

Hi @rHermes

This is Linux, right? Can you try running with GC_INITIAL_HEAP_SIZE=8g, GC_LIMIT=8g, or both (you can adjust the values even higher)? This seems to be an ongoing issue with our GC in high memory pressure environments.

rHermes commented 1 year ago

Hey, thanks for taking another look at the issue :)

I haven't build codon myself, just downloaded it via AUR, https://aur.archlinux.org/packages/codon-bin. Running with the two variables you provided @inumanag the program finished in debug mode and in release mode!

I tried with 14g for both values and it finished in both modes, same for 15g and 16g. This is on a laptop with 16GiB total.

And lastly, yes this is on linux.