private void LoadData(BatchInstruction instr, int[] rows, int rowIndex, int batchSize)
 {
     for (int i = 0; i < batchSize; ++i)
     {
         var row = rows[rowIndex] + i;
         instr.buf[i] = instr.weight * instr.data[row];
     }
 }
        private BatchInstruction[] Compile(ISymbolicExpressionTree tree, IDataset dataset, Func <ISymbolicExpressionTreeNode, byte> opCodeMapper)
        {
            var root = tree.Root.GetSubtree(0).GetSubtree(0);
            var code = new BatchInstruction[root.GetLength()];

            if (root.SubtreeCount > ushort.MaxValue)
            {
                throw new ArgumentException("Number of subtrees is too big (>65.535)");
            }
            int c = 1, i = 0;

            foreach (var node in root.IterateNodesBreadth())
            {
                if (node.SubtreeCount > ushort.MaxValue)
                {
                    throw new ArgumentException("Number of subtrees is too big (>65.535)");
                }
                code[i] = new BatchInstruction {
                    opcode     = opCodeMapper(node),
                    narg       = (ushort)node.SubtreeCount,
                    buf        = new double[BATCHSIZE],
                    childIndex = c
                };
                if (node is VariableTreeNode variable)
                {
                    code[i].weight = variable.Weight;
                    if (cachedData.ContainsKey(variable.VariableName))
                    {
                        code[i].data = cachedData[variable.VariableName];
                    }
                    else
                    {
                        code[i].data = dataset.GetReadOnlyDoubleValues(variable.VariableName).ToArray();
                        cachedData[variable.VariableName] = code[i].data;
                    }
                }
                else if (node is ConstantTreeNode constant)
                {
                    code[i].value = constant.Value;
                    for (int j = 0; j < BATCHSIZE; ++j)
                    {
                        code[i].buf[j] = code[i].value;
                    }
                }
                c += node.SubtreeCount;
                ++i;
            }
            return(code);
        }