private SparsityInfo CalculateSparsity(Instruction[] instructions, Dictionary <Variable, SparsityInfo> varmapping) { var instrs = new Stack <SparsityInfo>(); foreach (var i in instructions) { var smanip = i.GetStackManipulation(); var num = smanip.Pop.Num; var children = new SparsityInfo[num]; for (int n = 0; n < num; n++) { children[num - n - 1] = instrs.Pop(); } var sp = Invoke <int[]>(i, children, varmapping); var info = new SparsityInfo() { Dimension = smanip.Push.Dimension, Sparsity = sp }; instrs.Push(info); } return(instrs.Pop()); }
private SparsityInfo MakeSparse(State s) { SparsityInfo info; if (d_stateSparsity.TryGetValue(s, out info)) { return(info); } var instrs = new Stack <SparsityInfo>(); var newinst = new List <Instruction>(); bool didrepl = false; foreach (var i in s.Instructions) { var smanip = i.GetStackManipulation(); var num = smanip.Pop.Num; var children = new SparsityInfo[num]; for (int n = 0; n < num; n++) { children[num - n - 1] = instrs.Pop(); } var sp = Invoke <int[]>(i, children, null); var spi = new SparsityInfo() { Dimension = smanip.Push.Dimension, Sparsity = sp }; var newi = ReplaceSparse(i, spi, children); if (newi != null) { didrepl = true; newinst.Add(newi); } else if (newinst != null) { newinst.Add(i); } instrs.Push(spi); } if (didrepl) { s.Instructions = newinst.ToArray(); } info = instrs.Pop(); d_stateSparsity[s] = info; return(info); }
private Instruction ReplaceSparse(Instruction i, SparsityInfo sparsity, SparsityInfo[] children) { var f = i as InstructionFunction; if (f == null || !CanSparse((Cdn.MathFunctionType)f.Id)) { return(null); } int size = 0; int sp = 0; int maxs = 0; bool ismultidim = false; for (int ii = 0; ii < children.Length; ii++) { size += children[ii].Dimension.Size(); sp += children[ii].Sparsity.Length; if (!children[ii].Dimension.IsOne) { ismultidim = true; } var ms = children[ii].Dimension.Size() - children[ii].Sparsity.Length; if (ms > maxs) { maxs = ms; } } if (!ismultidim) { return(null); } if (maxs > 100) { // Too many calculations to special case return(null); } if (sp == 0 || (double)size / (double)sp < 0.1) { // Not sparse enough return(null); } return(new Cdn.RawC.Programmer.Instructions.SparseOperator(f, sparsity, children)); }
private int[] MatrixMultiplySparsity(SparsityInfo l, SparsityInfo r) { // Compute matrix multiply sparsity var s1 = l.Expand(); var s2 = r.Expand(); var ret = new List <int>(); int i = 0; for (int ci = 0; ci < r.Dimension.Columns; ci++) { for (int ri = 0; ri < l.Dimension.Rows; ri++) { bool issparse = true; for (int k = 0; k < r.Dimension.Rows; k++) { var p1i = ri + k * l.Dimension.Rows; var p1 = s1[p1i]; var p2i = k + ci * r.Dimension.Rows; var p2 = s2[p2i]; if (!p1 && !p2) { issparse = false; break; } } if (issparse) { ret.Add(i); } i++; } } return(ret.ToArray()); }