private Cdn.Expression Inline(Dictionary <Instruction, Instruction> instmap, Cdn.Expression expr) { List <Cdn.Instruction> instructions = new List <Instruction>(); foreach (Instruction inst in expr.Instructions) { InstructionVariable variable = inst as InstructionVariable; if (variable != null) { // See if we need to expand it Variable v = variable.Variable; if (State(v) == null) { if (variable.HasSlice) { // Need to promote it here. Inlining a slice is // complicated var s = ExpandedState(v); AddState(null, s); AddAux(s, null); } else { var sub = Inline(instmap, v.Expression); // Expand the instruction foreach (var i in sub.Instructions) { instructions.Add(i); } continue; } } } var cp = inst.Copy() as Instruction; if (instmap != null) { instmap.Add(inst, cp); } instructions.Add(cp); } var e = new Cdn.Expression(""); e.SetInstructionsTake(instructions.ToArray()); return(e); }
private int[] InstructionSparsity(InstructionVariable instr, SparsityInfo[] children, Dictionary <Variable, SparsityInfo> mapping) { var ret = VariableSparsity(instr.Variable, mapping); if (instr.HasSlice) { // Slice the sparsity also Dimension slicedim; var slice = instr.GetSlice(out slicedim); return(SparsitySlice(ret, slice)); } return(ret); }
private IEnumerable <VariableDependency> VariableExpressionDependencies(Cdn.Expression expr) { if (expr == null) { return(new VariableDependency[] {}); } if (s_variableDependencies == null) { s_variableDependencies = new Dictionary <Cdn.Expression, List <VariableDependency> >(); } List <VariableDependency> lst; if (s_variableDependencies.TryGetValue(expr, out lst)) { return(lst); } lst = new List <VariableDependency>(); s_variableDependencies[expr] = lst; foreach (var instr in expr.Instructions) { InstructionVariable v = instr as InstructionVariable; if (v != null) { lst.Add(new VariableDependency { Variable = v.Variable, Instruction = v }); } } foreach (var ex in expr.Dependencies) { lst.AddRange(VariableExpressionDependencies(ex)); } return(lst); }
protected virtual string Translate(InstructionVariable instruction, Context context) { Cdn.Variable prop = instruction.Variable; if (!context.Program.StateTable.Contains(prop)) { throw new NotImplementedException(String.Format("The variable `{0}' is not implemented", prop.FullName)); } DataTable.DataItem item = context.Program.StateTable[prop]; if (instruction.HasSlice) { Cdn.Dimension dim; int[] slice = instruction.GetSlice(out dim); if (context.SupportsFirstClassArrays) { return(String.Format("{0}[{1}][{2}]", context.This(context.Program.StateTable), item.AliasOrIndex, slice[0])); } else { return(String.Format("{0}[{1}]", context.This(context.Program.StateTable), context.AddedIndex(item, slice[0]))); } } else { return(String.Format("{0}[{1}]", context.This(context.Program.StateTable), item.AliasOrIndex)); } }
protected virtual string TranslateV(InstructionVariable instruction, Context context) { Cdn.Variable prop = instruction.Variable; if (!context.Program.StateTable.Contains(prop)) { throw new NotImplementedException(String.Format("The variable `{0}' is not implemented", prop.FullName)); } DataTable.DataItem item = context.Program.StateTable[prop]; string ret = null; if (!context.SupportsFirstClassArrays) { ret = context.PeekRet(); } int size = prop.Dimension.Size(); int offset = 0; if (instruction.HasSlice) { Cdn.Dimension dim; var slice = instruction.GetSlice(out dim); // This is a multidim slice for sure, check if it's just linear if (!Context.IndicesAreContinuous(slice)) { if (context.SupportsFirstClassArrays) { var v = context.This(context.Program.StateTable); var vi = String.Format("{0}[{1}]", v, item.AliasOrIndex); return(context.ArraySliceIndices(vi, slice)); } else { StringBuilder sret = new StringBuilder("("); // Make single element assignments for (int i = 0; i < slice.Length; ++i) { if (i != 0) { sret.Append(", "); } sret.AppendFormat("({0})[{1}] = {2}[{3}]", ret, i, context.This(context.Program.StateTable), context.AddedIndex(item, slice[i])); } sret.AppendFormat(", {0})", ret); return(sret.ToString()); } } else { offset = slice[0]; size = slice.Length; } } // Here we should return from "offset" to "offset + size" if (ret != null) { // We need to write the results in "ret". Make a memcpy return(context.MemCpy(ret, "0", context.This(context.Program.StateTable), context.AddedIndex(item, offset), "ValueType", size)); } else if (context.SupportsPointers) { // Simply return the correct offset of the continous slice return(String.Format("({0} + {1})", context.This(context.Program.StateTable), context.AddedIndex(item, offset))); } else if (context.SupportsFirstClassArrays) { // Simply return the slice var v = context.This(context.Program.StateTable); if (offset == 0 && size == item.Dimension.Size()) { return(String.Format("{0}[{1}]", v, item.AliasOrIndex)); } else { return(context.ArraySlice(String.Format("{0}[{1}]", v, item.AliasOrIndex), offset.ToString(), (offset + size).ToString())); } } else { throw new Exception("Unsupported multidim variable case!"); } }