Пример #1
0
        private static MethodBuilder BuildRunMethod <T, R>(Expression <Kernel <T, R> > kernel, TypeBuilder tb, FieldInfo xmin, FieldInfo xmax, FieldInfo ymin, FieldInfo ymax, FieldInfo source, FieldInfo target)
            where T : unmanaged
            where R : unmanaged
        {
            var km = KernelMeasure.Measure(kernel.Compile()); //TODO: perform an expression-only measure

            var staticRun = tb.DefineMethod("RunStatic", MethodAttributes.HideBySig | MethodAttributes.Private | MethodAttributes.Static, null, new[]
                                            { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(UnsafeArray2dPtr <T>), UnsafeArray2d.GetRefType <R>() });

            var xmin_arg   = Parameter(typeof(int), "xmin");
            var xmax_arg   = Parameter(typeof(int), "xmax");
            var ymin_arg   = Parameter(typeof(int), "ymin");
            var ymax_arg   = Parameter(typeof(int), "ymax");
            var height_arg = Parameter(typeof(int), "height");

            var sourcePtr_arg = Parameter(typeof(UnsafeArray2dPtr <T>), "sourcePtr");
            var targetPtr_arg = Parameter(UnsafeArray2d.GetRefType <R>(), "targetPtr");


            var i_var         = Variable(typeof(int), "i");
            var j_var         = Variable(typeof(int), "j");
            var w_var         = Variable(typeof(int), "w");
            var inlinedKernel = new CellAccessUnsafeInliner(kernel.Parameters[0], sourcePtr_arg, i_var, j_var, height_arg, w_var).Visit(kernel.Body);

            BlockExpression fe = null;

            if (typeof(T) == typeof(R)) // slight optimization
            {
                var l           = Label();
                var d_var       = Variable(typeof(int), "d");
                var lineEnd_var = Variable(typeof(UnsafeArray2dPtr <T>), "lineEnd");
                fe = Block(
                    new[] { w_var, d_var, lineEnd_var },
                    Assign(w_var, Property(sourcePtr_arg, typeof(UnsafeArray2dPtr <T>).GetProperty(nameof(UnsafeArray2dPtr <T> .Stride)))),
                    Assign(d_var, Subtract(targetPtr_arg, sourcePtr_arg)),
                    For(i_var,
                        xmin_arg,
                        LessThan(i_var, xmax_arg),
                        Constant(1),
                        Block(
                            Assign(lineEnd_var, Subtract(Add(sourcePtr_arg, ymax_arg), ymin_arg)),
                            Loop(
                                IfThenElse(
                                    LessThan(sourcePtr_arg, lineEnd_var),
                                    Block(
                                        Assign(
                                            MakeIndex(
                                                sourcePtr_arg,
                                                typeof(UnsafeArray2dPtr <T>).GetProperty("Item", new[] { typeof(int) }),
                                                new[] { d_var }
                                                ),
                                            inlinedKernel
                                            ),
                                        AddAssign(sourcePtr_arg, Constant(1)) // skip to the next element
                                        ),
                                    Break(l)
                                    ),
                                l
                                ),
                            AddAssign(sourcePtr_arg, Constant(km.ymax - km.ymin)) // skip to the next row
                            )
                        )
                    );
            }
            else
            {
                fe = Block(
                    new[] { w_var },
                    Assign(w_var, Property(sourcePtr_arg, typeof(UnsafeArray2dPtr <T>).GetProperty(nameof(UnsafeArray2dPtr <T> .Stride)))),
                    For(i_var,
                        xmin_arg,
                        LessThan(i_var, xmax_arg),
                        Constant(1),
                        Block(
                            For(
                                j_var,
                                ymin_arg,
                                LessThan(j_var, ymax_arg),
                                Constant(1),
                                Block(
                                    Assign(
                                        MakeIndex(
                                            targetPtr_arg,
                                            UnsafeArray2d.GetRefType <R>().GetProperty("Item", new[] { typeof(int) }),
                                            new[] { Constant(0) }
                                            ),
                                        inlinedKernel
                                        ),
                                    AddAssign(sourcePtr_arg, Constant(1)), // skip to the next element
                                    AddAssign(targetPtr_arg, Constant(1))
                                    )
                                ),
                            AddAssign(sourcePtr_arg, Constant(km.ymax - km.ymin)), // skip to the next row
                            AddAssign(targetPtr_arg, Constant(km.ymax - km.ymin))
                            )
                        )
                    );
            }
            LambdaExpression staticRunLambda = Lambda(fe, xmin_arg, xmax_arg, ymin_arg, ymax_arg, height_arg, sourcePtr_arg, targetPtr_arg);

            staticRunLambda.CompileToMethod(staticRun);


            return(BuildInstanceRun <T, R>(tb, xmin, xmax, ymin, ymax, source, target, staticRun));
        }
Пример #2
0
        private static MethodBuilder BuildRunMethod <R>(LambdaExpression kernel, TypeBuilder tb, FieldInfo xmin, FieldInfo xmax, FieldInfo ymin, FieldInfo ymax, IEnumerable <FieldInfo> sources, FieldInfo target, bool recurrent)
        {
            var km          = KernelMeasure.Measure(kernel); //TODO: perform an expression-only measure
            var sourceTypes = (from s in sources let elemType = s.FieldType.GetGenericArguments()[0] select typeof(UnsafeArray2dPtr <>).MakeGenericType(elemType)).ToArray();
            var paramTypes  = Enumerable.Repeat(typeof(int), 5)
                              .Concat(sourceTypes)
                              .Append(UnsafeArray2d.GetRefType <R>()).ToArray();

            var staticRun = tb.DefineMethod("RunStatic", MethodAttributes.HideBySig | MethodAttributes.Private | MethodAttributes.Static, null, paramTypes);

            var xmin_arg   = Parameter(typeof(int), "xmin");
            var xmax_arg   = Parameter(typeof(int), "xmax");
            var ymin_arg   = Parameter(typeof(int), "ymin");
            var ymax_arg   = Parameter(typeof(int), "ymax");
            var height_arg = Parameter(typeof(int), "height");

            var sourceArgs = new List <ParameterExpression>();
            var i          = 0;

            foreach (var s in sources)
            {
                sourceArgs.Add(Parameter(sourceTypes[i++], s.Name.Substring(1) + "Ptr"));
            }

            var targetPtr_arg = Parameter(UnsafeArray2d.GetRefType <R>(), "targetPtr");

            var paramMap = new Dictionary <ParameterExpression, ParameterExpression>();

            for (i = 0; i < sourceArgs.Count; i++)
            {
                //if(kernel.Parameters[i].Type.IsConstructedGenericType && kernel.Parameters[i].Type.GetGenericTypeDefinition() == typeof(ICell<>))
                paramMap.Add(kernel.Parameters[i], sourceArgs[i]);
            }

            if (recurrent)
            {
                paramMap.Add(kernel.Parameters[i], targetPtr_arg);
            }

            var i_var             = Variable(typeof(int), "i");
            var j_var             = Variable(typeof(int), "j");
            var w_var             = Variable(typeof(int), "w");
            var inlinedKernelBody = new CellAccessUnsafeInliner(paramMap, i_var, j_var, height_arg, w_var).Visit(kernel.Body);

            BlockExpression fe = null;
            {
                fe = Block(
                    new[] { w_var },
                    Assign(w_var, Property(targetPtr_arg, UnsafeArray2d.GetRefType <R>().GetProperty("Stride"))),
                    For(i_var,
                        xmin_arg,
                        LessThan(i_var, xmax_arg),
                        Constant(1),
                        Block(
                            For(
                                j_var,
                                ymin_arg,
                                LessThan(j_var, ymax_arg),
                                Constant(1),
                                Block(
                                    Assign(
                                        MakeIndex(
                                            targetPtr_arg,
                                            UnsafeArray2d.GetRefType <R>().GetProperty("Item", new[] { typeof(int) }),
                                            new[] { Constant(0) }
                                            ),
                                        inlinedKernelBody
                                        ),
                                    Block(from s in sourceArgs select AddAssign(s, Constant(1))), // skip to the next element
                                    AddAssign(targetPtr_arg, Constant(1))
                                    )
                                ),
                            Block(from s in sourceArgs select AddAssign(s, Constant(km.ymax - km.ymin))), // skip to the next row
                            AddAssign(targetPtr_arg, Constant(km.ymax - km.ymin))
                            )
                        )
                    );
            }
            LambdaExpression staticRunLambda = Lambda(fe, (new[] { xmin_arg, xmax_arg, ymin_arg, ymax_arg, height_arg }).Concat(sourceArgs).Append(targetPtr_arg));

            staticRunLambda.CompileToMethod(staticRun);


            return(BuildInstanceRun <R>(tb, xmin, xmax, ymin, ymax, sources, target, staticRun));
        }