[SYSTEMDS-2769] Fix lineage cache eviction test

This patch replaces the current cache eviction test script
with a better and robust (hopefully) one. This script simulates
a mini-batch scenario with batch-wise preprocessing, which can
be reused per epoch.
diff --git a/src/test/java/org/apache/sysds/test/functions/lineage/CacheEvictionTest.java b/src/test/java/org/apache/sysds/test/functions/lineage/CacheEvictionTest.java
index c2b79d3..fa9bae6 100644
--- a/src/test/java/org/apache/sysds/test/functions/lineage/CacheEvictionTest.java
+++ b/src/test/java/org/apache/sysds/test/functions/lineage/CacheEvictionTest.java
@@ -29,7 +29,6 @@
 import org.apache.sysds.runtime.lineage.Lineage;
 import org.apache.sysds.runtime.lineage.LineageCacheConfig;
 import org.apache.sysds.runtime.lineage.LineageCacheConfig.ReuseCacheType;
-import org.apache.sysds.runtime.lineage.LineageCacheEviction;
 import org.apache.sysds.runtime.lineage.LineageCacheStatistics;
 import org.apache.sysds.runtime.matrix.data.MatrixValue;
 import org.apache.sysds.test.TestConfiguration;
@@ -42,7 +41,7 @@
 public class CacheEvictionTest extends LineageBase {
 
 	protected static final String TEST_DIR = "functions/lineage/";
-	protected static final String TEST_NAME1 = "CacheEviction1";
+	protected static final String TEST_NAME1 = "CacheEviction2";
 
 	protected String TEST_CLASS_DIR = TEST_DIR + CacheEvictionTest.class.getSimpleName() + "/";
 	
@@ -65,17 +64,16 @@
 			LOG.debug("------------ BEGIN " + testname + "------------");
 			
 			/* This test verifies the order of evicted items w.r.t. the specified
-			 * cache policies. This test enables individual components of the 
-			 * scoring function by masking the other components, and compare the
-			 * order of evicted entries for different policies. HYBRID policy is 
-			 * not considered for this test as it is hard to anticipate the reuse
-			 * statistics if all the components are unmasked. 
+			 * cache policies, using a mini-batch wise autoencoder inspired
+			 * test script. An epoch-wise reusable scale and shift is part of
+			 * every batch processing. LRU fails to reuse the scale calls as
+			 * it tends to evicts scale and shift intermediates due to higher
+			 * number of post scale intermediates, where cost & size successfully
+			 * reuses all the reusable operations.
 			 * 
-			 * TODO: Test disk spilling, which will need some tunings in eviction
-			 * logic; otherwise the automated test might take significantly 
-			 * longer as eviction logic tends to just delete entries with little
-			 * computation and estimated I/O time. Note that disk spilling is 
-			 * already happening as part of other tests (e.g. MultiLogReg).
+			 * TODO: add DagHeight. All three policies perform as expected in my
+			 * laptop, but for some reasons, LRU performs better in github actions
+			 * - that leads to failed comparison between dagheight and LRU.
 			 */
 			
 			OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION = false;
@@ -84,8 +82,7 @@
 			getAndLoadTestConfiguration(testname);
 			fullDMLScriptName = getScript();
 			Lineage.resetInternalState();
-			long cacheSize = LineageCacheEviction.getCacheLimit();
-			LineageCacheConfig.setReusableOpcodes("exp", "+", "round");
+			LineageCacheConfig.setSpill(false); //disable spilling
 			
 			// LRU based eviction
 			List<String> proArgs = new ArrayList<>();
@@ -94,14 +91,12 @@
 			proArgs.add(ReuseCacheType.REUSE_FULL.name().toLowerCase());
 			proArgs.add("policy_lru");
 			proArgs.add("-args");
-			proArgs.add(String.valueOf(cacheSize));
 			proArgs.add(output("R"));
 			programArgs = proArgs.toArray(new String[proArgs.size()]);
 			runTest(true, EXCEPTION_NOT_EXPECTED, null, -1);
 			HashMap<MatrixValue.CellIndex, Double> R_lru = readDMLMatrixFromOutputDir("R");
-			long expCount_lru = Statistics.getCPHeavyHitterCount("exp");
 			long hitCount_lru = LineageCacheStatistics.getInstHits();
-			long evictedCount_lru = LineageCacheStatistics.getMemDeletes();
+			long colmeanCount_lru = Statistics.getCPHeavyHitterCount("uacmean");
 			
 			// costnsize scheme (computationTime/Size)
 			proArgs.clear();
@@ -110,35 +105,28 @@
 			proArgs.add(ReuseCacheType.REUSE_FULL.name().toLowerCase());
 			proArgs.add("policy_costnsize");
 			proArgs.add("-args");
-			proArgs.add(String.valueOf(cacheSize));
 			proArgs.add(output("R"));
 			programArgs = proArgs.toArray(new String[proArgs.size()]);
 			Lineage.resetInternalState();
 			runTest(true, EXCEPTION_NOT_EXPECTED, null, -1);
 			HashMap<MatrixValue.CellIndex, Double> R_costnsize= readDMLMatrixFromOutputDir("R");
-			long expCount_wt = Statistics.getCPHeavyHitterCount("exp");
-			long hitCount_wt = LineageCacheStatistics.getInstHits();
-			long evictedCount_wt = LineageCacheStatistics.getMemDeletes();
-			LineageCacheConfig.resetReusableOpcodes();
+			long hitCount_cs = LineageCacheStatistics.getInstHits();
+			long colmeanCount_cs = Statistics.getCPHeavyHitterCount("uacmean");
 			
 			// Compare results
 			Lineage.setLinReuseNone();
 			TestUtils.compareMatrices(R_lru, R_costnsize, 1e-6, "LRU", "costnsize");
-			
-			// Compare reused instructions
-			Assert.assertTrue(expCount_lru >= expCount_wt);
-			// Compare counts of evicted items
-			// LRU tends to evict more entries to recover equal amount of memory
-			// Note: changed to equals to fix flaky tests where both are not evicted at all
-			// (e.g., due to high execution time as sometimes observed through github actions)
-			Assert.assertTrue(("Violated expected evictions: "+evictedCount_lru+" >= "+evictedCount_wt),
-				evictedCount_lru >= evictedCount_wt);
 			// Compare cache hits
-			Assert.assertTrue(hitCount_lru < hitCount_wt);
+			Assert.assertTrue("Violated cache hit count: "+hitCount_lru+" < "+hitCount_cs, 
+					hitCount_lru < hitCount_cs);
+			// Compare reused instruction (uacmean) counts
+			Assert.assertTrue("Violated uacmean count: "+colmeanCount_cs+" < "+colmeanCount_lru, 
+					colmeanCount_cs < colmeanCount_lru);
 		}
 		finally {
 			OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION = old_simplification;
 			OptimizerUtils.ALLOW_SUM_PRODUCT_REWRITES = old_sum_product;
+			LineageCacheConfig.setSpill(true);
 			Recompiler.reinitRecompiler();
 		}
 	}
diff --git a/src/test/scripts/functions/lineage/CacheEviction2.dml b/src/test/scripts/functions/lineage/CacheEviction2.dml
new file mode 100644
index 0000000..f1297b7
--- /dev/null
+++ b/src/test/scripts/functions/lineage/CacheEviction2.dml
@@ -0,0 +1,61 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#-------------------------------------------------------------
+
+D = rand(rows=6400, cols=784, min=0, max=20, seed=42)
+bs = 32;
+ep = 10;
+iter_ep = ceil(nrow(D)/bs);
+maxiter = ep * iter_ep;
+beg = 1;
+iter = 0;
+i = 1;
+
+while (iter < maxiter) {
+  end = beg + bs - 1;
+  if (end>nrow(D))
+    end = nrow(D);
+  X = D[beg:end,]
+
+  #reusable OP across epochs
+  X = scale(X, TRUE, TRUE);
+  #pollute cache with not reusable OPs
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+  X = ((X + X) * i - X) / (i+1)
+
+  iter = iter + 1;
+  if (end == nrow(D))
+    beg = 1;
+  else
+    beg = end + 1;
+  i = i + 1;
+
+}
+R = X;
+write(R, $1, format="text");
+