changeset 31822:3e4e74ad8fd7

movfun.m: Fall back on algorithm using smaller memory blocks in case of OOM error (bug #63791). * movfun.m (movfun_oncol): Use try/catch block to attempt indexing operation which can require large memory allocation. If try code fails, then in catch block use a for loop with requests for smaller memory blocks to attempt the calculation.
author Rik <rik@octave.org>
date Mon, 13 Feb 2023 11:10:00 -0800
parents 6bf833d96cbe
children f14aea577cc5
files scripts/signal/movfun.m
diffstat 1 files changed, 17 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/signal/movfun.m	Sat Feb 11 09:57:47 2023 -0800
+++ b/scripts/signal/movfun.m	Mon Feb 13 11:10:00 2023 -0800
@@ -296,7 +296,23 @@
   y = NA (N, odim);
 
   ## Process center part
-  y(C,:) = fcn (x(slcidx));
+  try
+    y(C,:) = fcn (x(slcidx));
+  catch err
+    ## Operation failed, likely because of out-of-memory error for "x(slcidx)".
+    if (! strcmp (err.identifier, "Octave:bad-alloc"))
+      rethrow (err);
+    endif
+
+    ## Try divide and conquer approach with smaller slices of data.
+    ## For loops are slow, so don't try too hard with this approach.
+    Nslices = 8;  # configurable
+    idx1 = fix (linspace (1, numel (C), Nslices));
+    idx2 = fix (linspace (1, columns (slcidx), Nslices));
+    for i = 1 : Nslices-1
+      y(C(idx1(i):idx1(i+1)),:) = fcn (x(slcidx(:, idx2(i):idx2(i+1))));
+    endfor
+  end_try_catch
 
   ## Process boundaries
   if (! isempty (Cpre))