Ejemplo n.º 1
0
 private Structure(Structure parent, object target)
 {
     parent._nested_structures.Add(this);
     this._class_instance = target;
 }
Ejemplo n.º 2
0
        public Structure FindAllTargets(object obj)
        {
            Dictionary <Delegate, object> delegate_to_instance = new Dictionary <Delegate, object>();
            Delegate     lambda_delegate = (Delegate)obj;
            BindingFlags findFlags       = BindingFlags.NonPublic |
                                           BindingFlags.Public |
                                           BindingFlags.Static |
                                           BindingFlags.Instance |
                                           BindingFlags.InvokeMethod |
                                           BindingFlags.OptionalParamBinding |
                                           BindingFlags.DeclaredOnly;

            _control_flow_graph.Add(Campy.Types.Utils.ReflectionCecilInterop.ConvertToMonoCecilMethodDefinition(lambda_delegate.Method));
            _control_flow_graph.ExtractBasicBlocks();

            // Construct graph containing all objects used in lambda.
            StackQueue <object> stack = new StackQueue <object>();

            stack.Push(lambda_delegate);
            Campy.Graphs.GraphLinkedList <object> data_graph = new GraphLinkedList <object>();
            while (stack.Count > 0)
            {
                object node = stack.Pop();

                // Case 1: object is multicast delegate.
                // A multicast delegate is a list of delegates called in the order
                // they appear in the list.
                System.MulticastDelegate md = node as System.MulticastDelegate;
                if (md != null)
                {
                    foreach (System.Delegate node2 in md.GetInvocationList())
                    {
                        if ((object)node2 != (object)node)
                        {
                            if (Options.Singleton.Get(Options.OptionType.DisplayStructureComputation))
                            {
                                System.Console.WriteLine("Pushing2 " + MyToString(node2));
                            }
                            stack.Push(node2);
                        }
                    }
                    // Note, if multicast delegate, then it does not make sense to continue.
                    // Handle normal delegates.
                    //continue;
                }

                // Case 2: object is plain delegate.
                System.Delegate del = node as System.Delegate;
                if (del != null)
                {
                    object target = del.Target;
                    if (target == null)
                    {
                        // If target is null, then the delegate is a function that
                        // uses either static data, or does not require any additional
                        // data. If target isn't null, then it's probably a class.
                        target = Activator.CreateInstance(del.Method.DeclaringType);
                        if (data_graph.Vertices.Contains(target))
                        {
                            continue;
                        }
                        if (!delegate_to_instance.ContainsKey(del))
                        {
                            Debug.Assert(!TypesUtility.IsBaseType(target.GetType(), typeof(Delegate)));
                            data_graph.AddVertex(target);
                            delegate_to_instance.Add(del, target);
                            stack.Push(target);
                        }
                    }
                    else
                    {
                        // Target isn't null for delegate. Most likely, the method
                        // is part of the target, so let's assert that.
                        bool found = false;
                        foreach (System.Reflection.MethodInfo mi in target.GetType().GetMethods(findFlags))
                        {
                            if (mi == del.Method)
                            {
                                found = true;
                                break;
                            }
                        }
                        Debug.Assert(found);
                        if (Options.Singleton.Get(Options.OptionType.DisplayStructureComputation))
                        {
                            System.Console.WriteLine("Pushing " + MyToString(target));
                        }
                        if (delegate_to_instance.ContainsKey(del))
                        {
                            Debug.Assert(delegate_to_instance[del] == target);
                        }
                        else
                        {
                            delegate_to_instance.Add(del, target);
                        }
                        stack.Push(target);
                    }
                    continue;
                }

                if (data_graph.Vertices.Contains(node))
                {
                    continue;
                }

                Debug.Assert(!TypesUtility.IsBaseType(node.GetType(), typeof(Delegate)));
                data_graph.AddVertex(node);

                // Case 3: object is a class, and potentially could point to delegate.
                // Examine all fields, looking for list_of_targets.

                Type target_type = node.GetType();

                FieldInfo[] target_type_fieldinfo = target_type.GetFields();
                foreach (var field in target_type_fieldinfo)
                {
                    var value = field.GetValue(node);
                    if (value != null)
                    {
                        if (field.FieldType.IsValueType)
                        {
                            continue;
                        }
                        if (TypesUtility.IsCampyArrayType(field.FieldType))
                        {
                            continue;
                        }
                        if (TypesUtility.IsSimpleCampyType(field.FieldType))
                        {
                            continue;
                        }
                        // chase pointer type.
                        if (Options.Singleton.Get(Options.OptionType.DisplayStructureComputation))
                        {
                            System.Console.WriteLine("Pushingf " + MyToString(value));
                        }
                        stack.Push(value);
                    }
                }
            }

            if (Options.Singleton.Get(Options.OptionType.DisplayStructureComputation))
            {
                System.Console.WriteLine();
                System.Console.WriteLine("Dump of nodes.");
                foreach (object node in data_graph.Vertices)
                {
                    System.Console.WriteLine("Node "
                                             + MyToString(node));
                    System.Console.WriteLine("typeof node = "
                                             + node.GetType());
                    System.Console.WriteLine("Node "
                                             + (((node as Delegate) != null) ? "is " : "is not ")
                                             + "a delegate.");
                    System.Console.WriteLine();
                }
            }

            // Add edges.
            foreach (object node in data_graph.Vertices)
            {
                Type node_type = node.GetType();

                FieldInfo[] node_type_fieldinfo = node_type.GetFields();
                foreach (var field in node_type_fieldinfo)
                {
                    if (field.FieldType.IsValueType)
                    {
                        continue;
                    }
                    if (TypesUtility.IsCampyArrayType(field.FieldType))
                    {
                        continue;
                    }
                    if (TypesUtility.IsSimpleCampyType(field.FieldType))
                    {
                        continue;
                    }
                    var value = field.GetValue(node);
                    if (value == null)
                    {
                    }
                    else if (TypesUtility.IsBaseType(value.GetType(), typeof(Delegate)))
                    {
                        Delegate del          = value as Delegate;
                        object   value_target = del.Target;
                        if (value_target == node)
                        {
                            ;
                        }
                        else if (value_target != null)
                        {
                            Debug.Assert(data_graph.Vertices.Contains(node));
                            Debug.Assert(data_graph.Vertices.Contains(value_target));
                            data_graph.AddEdge(node, value_target);
                        }
                        else
                        {
                            value_target = delegate_to_instance[del];
                            if (value_target != node)
                            {
                                Debug.Assert(data_graph.Vertices.Contains(node));
                                Debug.Assert(data_graph.Vertices.Contains(value_target));
                                data_graph.AddEdge(node, value_target);
                            }
                        }
                    }
                    else
                    {
                        Debug.Assert(data_graph.Vertices.Contains(node));
                        Debug.Assert(data_graph.Vertices.Contains(value));
                        data_graph.AddEdge(node, value);
                    }
                }
            }

            if (Options.Singleton.Get(Options.OptionType.DisplayStructureComputation))
            {
                foreach (object node in data_graph.Vertices)
                {
                    System.Console.WriteLine("Node "
                                             + MyToString(node));
                    System.Console.WriteLine("typeof node = "
                                             + node.GetType());
                    System.Console.WriteLine("Node "
                                             + (((node as Delegate) != null) ? "is " : "is not ")
                                             + "a delegate.");
                    foreach (object succ in data_graph.Successors(node))
                    {
                        System.Console.WriteLine("-> "
                                                 + succ.GetHashCode() + " " + MyToString(succ));
                    }
                    System.Console.WriteLine();
                }
                System.Console.WriteLine();
            }

            Structure res = Structure.Initialize(delegate_to_instance, lambda_delegate.Method, data_graph, _control_flow_graph);

            if (Options.Singleton.Get(Options.OptionType.DisplayStructureComputation))
            {
                res.Dump();
            }

            return(res);
        }
Ejemplo n.º 3
0
        private static void AssignmentManagedStruct(Structure structure, ref object staging_object)
        {
            Type s = staging_object.GetType();

            SR.FieldInfo[] sfi = s.GetFields();
            foreach (SR.FieldInfo fi in structure.simple_fields)
            {
                object field_value = fi.GetValue(structure._class_instance);
                String na          = fi.Name;
                String tys         = Campy.Utils.Utility.GetFriendlyTypeName(fi.FieldType);
                // Copy.
                SR.FieldInfo hostObjectField = fi;
                object       value           = field_value;
                // Never copy tile_statics...
                if (TypesUtility.IsCampyTileStaticType(fi.FieldType))
                {
                    continue;
                }
                var deviceObjectField = sfi.Where(f => f.Name == fi.Name).FirstOrDefault();
                if (deviceObjectField == null)
                {
                    throw new ArgumentException("Field not found.");
                }
                if (field_value != null)
                {
                    deviceObjectField.SetValue(staging_object, value);
                }
                else
                {
                    // In order to prevent a lot of segv's ...
                    // Create a default value based on field type?
                    if (TypesUtility.IsCampyArrayViewType(fi.FieldType))
                    {
                        deviceObjectField.SetValue(staging_object, Array_View <int> .Default_Value);
                    }
                    else if (TypesUtility.IsCampyArrayType(fi.FieldType))
                    {
                        deviceObjectField.SetValue(staging_object, Array <int> .Default_Value);
                    }
                    else if (TypesUtility.IsCampyAcceleratorType(fi.FieldType))
                    {
                        deviceObjectField.SetValue(staging_object, Accelerator.Default_Value);
                    }
                    else if (TypesUtility.IsCampyAcceleratorViewType(fi.FieldType))
                    {
                        deviceObjectField.SetValue(staging_object, Accelerator_View.Default_Value);
                    }
                    else if (TypesUtility.IsCampyIndexType(fi.FieldType))
                    {
                        deviceObjectField.SetValue(staging_object, Index.Default_Value);
                    }
                    else if (TypesUtility.IsCampyExtentType(fi.FieldType))
                    {
                        deviceObjectField.SetValue(staging_object, Extent.Default_Value);
                    }
                    else
                    {
                    }
                }
            }
            // Add in other structures.
            foreach (Structure child in structure.nested_structures)
            {
                SR.FieldInfo sn = sfi.Where(f => child.Name == f.Name).FirstOrDefault();
                if (sn == null)
                {
                    throw new ArgumentException("Field not found.");
                }
                object vsn = sn.GetValue(staging_object);
                if (vsn == null)
                {
                    throw new ArgumentException("Value not found.");
                }
                AssignmentManagedStruct(child, ref vsn);
            }
        }
Ejemplo n.º 4
0
        // Create an intermediate representation of data_graph and control_flow_graph
        // that contains the nodes in the graphs as Structures, and edges between
        // nodes represented by nesting of Structures. This representation is
        // needed for translation to C++ AMP.
        public static Structure Initialize(Dictionary <Delegate, object> delegate_to_instance, System.Reflection.MethodInfo main_method, GraphLinkedList <object> data_graph, CFG control_flow_graph)
        {
            map_target_to_structure = new Dictionary <object, Structure>();
            Structure top_level_structure = new Structure();
            var       ddlist = data_graph.Vertices;
            object    dd     = data_graph.Vertices.First();

            top_level_structure._class_instance = dd;
            top_level_structure._main_method    = main_method;
            int    last_depth  = 1;
            String last_prefix = "";

            top_level_structure.Name     = "s" + last_depth;
            top_level_structure.FullName = last_prefix + top_level_structure.Name;
            top_level_structure.level    = last_depth;
            List <object>          targets             = new List <object>();
            StackQueue <String>    stack_of_prefix     = new StackQueue <string>();
            StackQueue <object>    stack_of_nodes      = new StackQueue <object>();
            StackQueue <Structure> stack_of_structures = new StackQueue <Structure>();

            stack_of_prefix.Push(last_prefix);
            stack_of_nodes.Push(dd);
            stack_of_structures.Push(top_level_structure);
            Dictionary <object, int> depth = new Dictionary <object, int>();

            depth.Add(dd, last_depth);
            while (stack_of_nodes.Count > 0)
            {
                object current_node   = stack_of_nodes.Pop();
                String current_prefix = stack_of_prefix.Pop();
                int    current_depth  = depth[current_node];
                if (targets.Contains(current_node))
                {
                    continue;
                }

                object target = current_node;
                targets.Add(target);
                if (Options.Singleton.Get(Options.OptionType.DisplayStructureComputation))
                {
                    System.Console.WriteLine("Target " + Utility.GetFriendlyTypeName(target.GetType()));
                }

                foreach (object next in data_graph.Successors(current_node))
                {
                    stack_of_nodes.Push(next);
                    depth.Add(next, current_depth + 1);
                    stack_of_prefix.Push(current_prefix + "s" + current_depth + ".");
                }
                if (current_depth > last_depth)
                {
                    Structure p = stack_of_structures.PeekTop();
                    stack_of_structures.Push(new Structure(p, target));
                    Structure c = stack_of_structures.PeekTop();
                    c.Name     = "s" + current_depth;
                    c.FullName = current_prefix + c.Name;
                    c.level    = current_depth;
                }
                else if (current_depth < last_depth)
                {
                    stack_of_structures.Pop();
                }

                Structure current_structure = stack_of_structures.PeekTop();
                current_structure._delegate_fields = new List <Tuple <System.Reflection.FieldInfo, Delegate> >();
                current_structure._class_fields    = new List <Tuple <System.Reflection.FieldInfo, object> >();

                last_depth  = current_depth;
                last_prefix = current_prefix;
                Structure try_structure = null;
                map_target_to_structure.TryGetValue(target, out try_structure);
                if (try_structure != null)
                {
                    Debug.Assert(try_structure == current_structure);
                }
                else
                {
                    map_target_to_structure.Add(target, current_structure);
                }
                Type target_type = target.GetType();
                foreach (FieldInfo fi in target_type.GetFields())
                {
                    // Add field if it's a simple value type or campy type.
                    // If it's a class, we'll be converting it into a struct.
                    object field_value = fi.GetValue(target);
                    if (field_value as System.Delegate == null &&
                        (fi.FieldType.IsValueType ||
                         TypesUtility.IsSimpleCampyType(fi.FieldType)))
                    {
                        current_structure.AddField(fi);
                    }
                    else if (field_value != null && field_value as System.Delegate == null)
                    {
                        // It's a class. Note rewrite here.
                        current_structure._class_fields.Add(new Tuple <System.Reflection.FieldInfo, object>(fi, field_value));
                    }

                    // When field of the target/class is a delegate, the intent in the code
                    // is to call the delegate via the field. Since pointers to anything
                    // are not allowed in C++ AMP, we need to actually either rewrite the
                    // structure so that the field is a method (not preferred),
                    // rewrite the name to the true name of the method called, or
                    // rewrite the method to be the name of the field (not preferred).
                    // In any case, note the association of the field with
                    // the delegate.
                    Type field_type = fi.FieldType;
                    if (field_value != null && TypesUtility.IsBaseType(field_type, typeof(Delegate)))
                    {
                        Delegate d = field_value as Delegate;
                        current_structure._delegate_fields.Add(new Tuple <System.Reflection.FieldInfo, Delegate>(fi, d));
                    }
                }
            }

            //foreach (object node in data_graph.Vertices)
            //{
            //    Structure current_structure = null;
            //    map_target_to_structure.TryGetValue(node, out current_structure);
            //    if (current_structure != null)
            //    {
            //        foreach (Tuple<object, string> pair in _class_fields)
            //        {
            //            if (pair.Item1 == node)
            //                current_structure.rewrite_names.Add(pair.Item2);
            //        }
            //    }
            //}

            // Add methods from control flow graph.
            foreach (CFG.CFGVertex node in control_flow_graph.VertexNodes)
            {
                if (node.IsEntry)
                {
                    // Scan structure and see if the instance contains the method.
                    foreach (KeyValuePair <object, Structure> pair in map_target_to_structure)
                    {
                        object    o = pair.Key;
                        Structure s = pair.Value;
                        Type      t = o.GetType();
                        Mono.Cecil.TypeDefinition td = node.Method.DeclaringType;
                        Type tdt = Campy.Types.Utils.ReflectionCecilInterop.ConvertToSystemReflectionType(td);
                        if (tdt == t)
                        {
                            // Add method to structure.
                            MethodBase mi = Campy.Types.Utils.ReflectionCecilInterop.ConvertToSystemReflectionMethodInfo(node.Method);
                            s.AddMethod(mi);
                            // Get calls.
                            foreach (CFG.CFGVertex c in control_flow_graph.AllInterproceduralCalls(node))
                            {
                                MethodBase mic = Campy.Types.Utils.ReflectionCecilInterop.ConvertToSystemReflectionMethodInfo(c.Method);
                                s.AddMethod(mic);
                            }
                        }
                    }
                }
            }


            // For each field that is a delegate, find the target structure corresponding to the delegate,
            // and add the delegate method to the structure.
            foreach (KeyValuePair <Delegate, object> pair in delegate_to_instance)
            {
                Delegate  k = pair.Key;
                object    v = pair.Value;
                Structure target_structure = null;
                map_target_to_structure.TryGetValue(v, out target_structure);
                Debug.Assert(target_structure != null);
                target_structure.AddMethod(k.Method);
            }

            //stack_of_structures = new StackQueue<Structure>();
            //stack_of_structures.Push(top_level_structure);
            //while (stack_of_structures.Count > 0)
            //{
            //    Structure cur_structure = stack_of_structures.Pop();
            //    foreach (Tuple<System.Reflection.FieldInfo, Delegate> tuple in cur_structure._delegate_fields)
            //    {
            //        if (tuple.Item2.Target != null)
            //        {
            //            Structure target_structure = null;
            //            map_target_to_structure.TryGetValue(tuple.Item2.Target, out target_structure);
            //            Debug.Assert(target_structure != null);
            //            target_structure.AddMethod(tuple.Item2.Method, tuple.Item2.Method.Name);
            //        }
            //        else
            //        {
            //            // Target empty. Map delegate to target.

            //        }
            //    }
            //    foreach (Structure child in cur_structure.nested_structures)
            //    {
            //        stack_of_structures.Push(child);
            //    }
            //}

            return(top_level_structure);
        }
Ejemplo n.º 5
0
        private static Type GetThunk(Delegate kernel, Campy.Types.Extent extent, Structure structure)
        {
            // Get MethodInfo for lambda.
            SR.MethodInfo mi               = kernel.Method;
            object        target           = kernel.Target;
            Type          target_type      = target.GetType();
            String        target_type_name = target_type.FullName;

            target_type_name = Campy.Utils.Utility.NormalizeSystemReflectionName(target_type_name);

            // Get assembly name which encloses code for kernel.
            String kernel_assembly_file_name = mi.DeclaringType.Assembly.Location;

            // Get directory containing the assembly.
            String full_path = Path.GetFullPath(kernel_assembly_file_name);

            full_path = Path.GetDirectoryName(full_path);

            // Get full name of kernel, including normalization because they cannot be compared directly with Mono.Cecil names.
            String kernel_full_name = string.Format("{0} {1}.{2}({3})", mi.ReturnType.FullName, Campy.Utils.Utility.RemoveGenericParameters(mi.ReflectedType), mi.Name, string.Join(",", mi.GetParameters().Select(o => string.Format("{0}", o.ParameterType)).ToArray()));

            kernel_full_name = Campy.Utils.Utility.NormalizeSystemReflectionName(kernel_full_name) + "_managed";

            // Get short name of Campy kernel.
            String campy_kernel_class_short_name = target_type_name
                                                   + "_managed";

            // Derive name of assembly containing corresponding Campy code for lambda.
            String campy_assembly_file_name = full_path + "\\" + kernel_full_name;

            //String ext = Path.GetExtension(campy_assembly_file_name);
            //campy_assembly_file_name = campy_assembly_file_name.Replace(ext, "");
            campy_assembly_file_name = campy_assembly_file_name + "_aux";
            campy_assembly_file_name = campy_assembly_file_name + ".dll";

            bool rebuild = false;

            SR.Assembly dll   = null;
            Type        thunk = null;

            // Determine if this campy assembly has been seen before.
            Assembly assembly = null;
            bool     found    = assemblies.TryGetValue(campy_assembly_file_name, out assembly);

            if (!found)
            {
                assembly = new Assembly(campy_assembly_file_name);
                assemblies.Add(campy_assembly_file_name, assembly);
            }

            // Create app domain in order to test the dll.
            //SR.AssemblyName assemblyName = new SR.AssemblyName();
            //assemblyName.CodeBase = assembly.Name;
            try
            {
                dll = SR.Assembly.LoadFile(campy_assembly_file_name);
            }
            catch
            {
                rebuild = true;
            }


            // Determine if this kernel has been executed before.
            if (!assembly.executed_lambdas.Contains(kernel_full_name))
            {
                // Check timestamps.
                if (!rebuild)
                {
                    DateTime dt_kernel_assembly       = File.GetLastWriteTime(kernel_assembly_file_name);
                    DateTime dt_campy_kernel_assembly = File.GetLastWriteTime(campy_assembly_file_name);
                    if (dt_campy_kernel_assembly < dt_kernel_assembly)
                    {
                        rebuild = true;
                    }
                }

                if (!rebuild)
                {
                    //dll = dom.Load(assemblyName);

                    // Get address of thunk class corresponding to lambda.
                    thunk = dll.GetType(kernel_full_name);
                    if (thunk == null)
                    {
                        rebuild = true;
                    }
                }

                if (rebuild)
                {
                    Converter converter = new Converter(assembly);

                    // Convert lambda into GPU target code.
                    converter.Convert(kernel, extent, structure);

                    // Compile target code into object code.
                    builder.Compile(assembly);

                    // Link object code.
                    builder.Link(assembly);
                }

                // Note that lambda was generated and compiled.
                assembly.executed_lambdas.Add(kernel_full_name);
            }

            // Load/reload assembly.
            //dll = dom.Load(assemblyName);
            dll = SR.Assembly.LoadFile(campy_assembly_file_name);

            // Get address of thunk class corresponding to lambda.
            thunk = dll.GetType(kernel_full_name);

            return(thunk);
        }