Skip to content

Allow setting torch_semiring_einsum block_size - #170

Open
ccshan wants to merge 5 commits into
mainfrom
block_size
Open

ccshan wants to merge 5 commits into
mainfrom
block_size

Conversation

@ccshan

@ccshan ccshan commented Jun 29, 2023

Copy link
Copy Markdown
Collaborator

The default was AutomaticBlockSize(max_cpu_bytes = 1 << 30), which means to use up to 1GB of memory (unless any block size would use >1GB). Setting bin/sum_product.py -B 64 makes a difference for parsing long strings.

The default was AutomaticBlockSize(max_cpu_bytes = 1 << 30), which means
to use up to 1GB of memory (unless any block size would use >1GB).
Setting `bin/sum_product.py -B 64` makes a difference for parsing long strings.
@ccshan
ccshan requested a review from davidweichiang June 29, 2023 08:20
@davidweichiang

Copy link
Copy Markdown
Collaborator

Is there any way to do this without passing the block_size option through so many functions? Like hide multiple options inside an "Options" object?

Chung-chieh Shan added 4 commits June 30, 2023 17:14
This commit eliminates the following out-of-memory error when parsing a
string of length 93:
```
Traceback (most recent call last):
  File "fggs/bin/sum_product.py", line 91, in <module>
    zs = fggs.sum_products(fgg, method=args.method, tol=args.tol, kmax=args.kmax)
  File "fggs/fggs/sum_product.py", line 455, in sum_products
    comp_values = SumProduct.apply_to_patterned_tensors(fgg, comp_opts, inputs.keys(), comp_labels, *inputs.values())
  File "fggs/fggs/sum_product.py", line 412, in apply_to_patterned_tensors
    (nonphysicals, *physicals) = SumProduct.apply(
  File "python/lib/python3.8/site-packages/torch/autograd/function.py", line 506, in apply
    return super().apply(*args, **kwargs)  # type: ignore[misc]
  File "fggs/fggs/sum_product.py", line 362, in forward
    newton(lambda x: F(fgg, x, inputs, semiring),
  File "fggs/fggs/sum_product.py", line 97, in newton
    dX = multi_solve(JF, F0 - x0)
  File "fggs/fggs/multi.py", line 224, in multi_solve
    b[z].copy_(a[z,z].solve(b[z], semiring))
  File "fggs/fggs/indices.py", line 1305, in solve
    x = semiring.solve(dense_a, dense_b)
  File "fggs/fggs/semirings.py", line 142, in solve
    return Semiring.solve(self, a, b)
  File "fggs/fggs/semirings.py", line 83, in solve
    a[:,k+1:] = self.add(a[:,k+1:], self.mul(a[:,k,None], a[k,k+1:]))
  File "fggs/fggs/semirings.py", line 107, in mul
    return x.mul(y).nan_to_num_(nan=0., posinf=inf)
RuntimeError: [enforce fail at alloc_cpu.cpp:75] err == 0. DefaultCPUAllocator: can't allocate memory: you tried to allocate 10207632960 bytes. Error code 12 (Cannot allocate memory)
```

Unfortunately we can't use `addcmul_` because we need `nan_to_num_`

To do: allow setting `block_size` instead of `AUTOMATIC_BLOCK_SIZE`
alongside dtype and device

The diff is much smaller now
@davidweichiang

Copy link
Copy Markdown
Collaborator

Which way (extra argument vs. hidden inside Semiring) do you like better? Could the argument you made about different einsums in the same computation requiring different block sizes apply to hiding the block size inside Semiring?

@ccshan

ccshan commented Jun 30, 2023

Copy link
Copy Markdown
Collaborator Author

Which way (extra argument vs. hidden inside Semiring) do you like better? Could the argument you made about different einsums in the same computation requiring different block sizes apply to hiding the block size inside Semiring?

The hidden-inside-Semiring way is growing on me; it helps that it makes the diff much smaller. I thought about different einsums in the same computation and feel that they would have different Semirings (so could still have different block sizes).

Comment thread fggs/semirings.py
a[:,k] = self.mul(a[:,k], self.star(a[k,k]))
for rows, cols in equation.block_sizes_to_indexes((a.shape[0], a.shape[1]-k-1), block_sizes):
cols = slice(cols.start+k+1, cols.stop+k+1, cols.step)
a[rows,cols] = self.add(a[rows,cols], self.mul(a[rows,k,None], a[k,cols]))

@ccshan ccshan Jun 30, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My ulimit -v is 64GB but I had to lower max_cpu_bytes to 4GB in order for this self.mul(a[rows,k,None], a[k,cols]) to not run out of memory. I guess it was because there were other things in memory already. It would be nice for get_available_bytes to take current memory use into account (bdusell/semiring-einsum#37).

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