ERROR: Not enough resources: table_space - How can I increase table space?

Happy New Year all!

ERROR: Not enough resources: table_space
^  Exception: (38) catch('$tabling':create_table(<trie>(0x1ebcc60), ret(_526782, _526784), user:move(_526782, _526784
), evaluation:call(<closure>(move/2)(_526782, _526784))), deadlock, '$tabling':restart_tabling(<closure>(move/2), use
r:move(_526782, _526784), evaluation:call(<closure>(move/2)(_526782, _526784)))) ? creep

I’m getting this error probably because I’m doing something silly and trying to table a predicate with a definition that really shouldn’t be that large. Until I can find the source of the problem and fix it at the root, how can I increase table space?

I know there is a command line option for that, --table_space=Size, but can I do it with a directive from inside a source file?

Edit: Additionally, what predicates can I use to get information about tables, like their size or currently tabled predicates and so on?

Cheers,
Stassa

Edit: added a bit more error context.

?- set_prolog_flag(table_space, <Bytes>).

That is a field that is developing. Currently there are two ways. One is using my personal Prolog lib, to be installed in ~/.config/swi-prolog/lib (see also the README.md of the repo for installation instructions). In this library you find tstat.pl and tdump.pl with several utility predicates.

The second route is to use WebStat, which provides a web interface for exploring (currently notably) table related statistical information. Eventually this should grow to a full blown web UI to explore just about any aspect of your program. Help is welcome!

2 Likes

Happy New Year, Jan!

?- set_prolog_flag(table_space, <Bytes>).

Thanks! I should have tried that on my own, but somehow I managed to miss it when I looked at the documentation online a few days ago.

Btw, I managed to eliminate the error. Unfortunately, I am not sure exactly what did it. I made a change where, before, I would call untable/1 inside the cleanup “block” of a setup_call_cleanup/3 call. On a hunch, I copied the untable/1 call inside the call “block” of setup_call_cleanup/3.

So my code was originaly like this:

S = (table(F/A)
     % other setups
     )
,G = % main goal
,C = (untable(F/A)
      % other cleanup
      )
,setup_call_cleanup(S,G,C)

And now it’s like this (and it doesn’t raise the error anymore):

S = (table(F/A)
     % other setups
     )
,G = ( % main goal
      ,untable(F/A)
     )
,C = (untable(F/A)
      % other cleanup
      )
,setup_call_cleanup(S,G,C)

Is it possible this did something to avoid the error? I noticed the exception said something about a deadlock.

Cheers,
Stassa

I don’t know. Note that dynamically switching on/off tabling for a predicate is a pretty weird thing to do. It might be that SWI-Prolog is the only implementation that allows you to do so (and as most test cases come from XSB, it is not tested much). Can you produce a test case? What are you trying to accomplish?

It seems I was a bit hasty about having eliminated the error because it looks like it happened again (I couldn’t collect the output but my code exited before it should and I’m guessing that’s the reason).

I’m not sure about a test case. I’m running an experiment comparing two ILP algorithms on the same dataset and running the same experiment code and evaluation code. The tabling/untabling is in the shared evaluation library. One algorithm is erroring out of table_space most likely because it’s producing a very large result, on the order of a couple thousand clauses that is then tabled (the result is a learned program that may include left-recursive clauses which I table to avoid it entering an infinite recursion before evaluation).

It’s hard to produce a test case because the error seems to happen at the very end of the experiment and tests on shorter runs that also produce the same size of learned program do not raise the error (which makes me suspect some kind of memory leak, either in my code or, well, yours).

What I could do is to add you as a collaborator to the private github repository for the experiment code that includes everything you need to run it and reproduce the error. It includes a bash script that runs the experiment plus two other experiments that don’t cause the same trouble. You can run the errorring experiment in isolation by commenting out a few lines on the script, which I’ll explain.

Would that work? Otherwise I can always try to increase table space… It’s just that the full experiment can take a while (I think about half to one hour, I haven’t been timing it precisely).