예제 #1
0
        public HlGraphEntry(HighLevel.HlGraph HlGraph, List <HighLevel.ArgumentLocation> fromInclusiveLocation, List <HighLevel.ArgumentLocation> toExclusiveLocation)
        {
            m_HlGraph = HlGraph;

            m_fromInclusiveLocation = fromInclusiveLocation;
            m_toExclusiveLocation   = toExclusiveLocation;
        }
예제 #2
0
            public static bool Do(HlGraph Graph)
            {
                DataFlow <LocationList> .Result DfResult = DoDF(Graph);

                List <Location> DeadDefinitionList = new List <Location>();

                bool Changed = false;

                foreach (BasicBlock BasicBlock in Graph.BasicBlocks)
                {
                    DeadDefinitionList.Clear();

                    LocationList List = DfResult.ExitState[BasicBlock];
                    if (List == null)
                    {
                        System.Diagnostics.Debug.Assert(BasicBlock == Graph.CanonicalExitBlock);
                    }
                    else
                    {
                        DeadDefinitionList.AddRange(List);
                    }

                    Changed |= ForBlock(BasicBlock, ref DeadDefinitionList);
                }
                return(Changed);
            }
예제 #3
0
        internal static HlGraphEntry ConstructRelatedHlGraphEntry(MethodInfo Method, HighLevel.HlGraph ParentGraph, HlGraphCache RelatedGraphCache)
        {
            HlGraphEntry CacheEntry = ConstructHlGraphEntry(Method, 0, false, "Cil2OpenCL_Sub_Seq{0}");

            RelatedGraphCache.SetValue(IntPtr.Zero, Method, CacheEntry);
            ParentGraph.RelatedGraphs[Method] = CacheEntry;

            GenerateOpenCLSource(CacheEntry);
            return(CacheEntry);
        }
예제 #4
0
        private static string getOpenCLSource(HighLevel.HlGraph HLgraph)
        {
            using (StringWriter Srcwriter = new StringWriter())
            {
                OpenCLInterop.WriteOpenCL(HLgraph, Srcwriter);
                string OpenClSource = Srcwriter.ToString();

                if (DumpCode > 2)
                {
                    System.Console.WriteLine(OpenClSource);
                }

                return(OpenClSource);
            }
        }
예제 #5
0
        public InvokeContext(HighLevel.HlGraph HLgraph, int RandomSeed)
        {
            m_ValueTypeMap = HLgraph.ValueTypeMap;
            m_Arguments    = new List <InvokeArgument>(HLgraph.Arguments.Count);
            for (int i = 0; i < HLgraph.Arguments.Count; i++)
            {
                System.Diagnostics.Debug.Assert(HLgraph.Arguments[i].Index == i);
                m_Arguments.Add(null);
            }

            if (!object.ReferenceEquals(HLgraph.RandomSeedArgument, null))
            {
                PutArgument(HLgraph.RandomSeedArgument, RandomSeed);
            }
        }
예제 #6
0
        private static void DoInvoke(int[] WorkSize, object Target, HlGraphEntry CacheEntry, InvokeContext ctx, OpenCLNet.Device device)
        {
            HighLevel.HlGraph HLgraph = CacheEntry.HlGraph;

            foreach (KeyValuePair <FieldInfo, HighLevel.ArgumentLocation> Entry in HLgraph.StaticFieldMap)
            {
                ctx.PutArgument(Entry.Value, Entry.Key.GetValue(null));
            }

            SetArguments(ctx, Target, HLgraph.RootPathEntry);

            /*
             * foreach (KeyValuePair<FieldInfo, HighLevel.ArgumentLocation> Entry in HLgraph.ThisFieldMap)
             * {
             *  ctx.PutArgument(Entry.Value, Entry.Key.GetValue(Target));
             * }
             * foreach (KeyValuePair<FieldInfo, Dictionary<FieldInfo, HighLevel.ArgumentLocation>> Entry in HLgraph.OuterThisFieldMap) {
             *  object RealThis = Entry.Key.GetValue(Target);
             *  foreach (KeyValuePair<FieldInfo, HighLevel.ArgumentLocation> SubEntry in Entry.Value) {
             *      ctx.PutArgument(SubEntry.Value, SubEntry.Key.GetValue(RealThis));
             *  }
             * }*/

            foreach (KeyValuePair <HighLevel.ArgumentLocation, HighLevel.ArrayInfo> Entry in HLgraph.MultiDimensionalArrayInfo)
            {
                System.Diagnostics.Debug.Assert(Entry.Key.Index >= 0 && Entry.Key.Index < ctx.Arguments.Count);
                InvokeArgument BaseArrayArg = ctx.Arguments[Entry.Key.Index];
                System.Diagnostics.Debug.Assert(BaseArrayArg != null && BaseArrayArg.Value != null && BaseArrayArg.Value.GetType() == Entry.Key.DataType);
                System.Diagnostics.Debug.Assert(Entry.Key.DataType.IsArray && Entry.Key.DataType.GetArrayRank() == Entry.Value.DimensionCount);
                System.Diagnostics.Debug.Assert(BaseArrayArg.Value is Array);

                Array BaseArray  = (System.Array)BaseArrayArg.Value;
                long  BaseFactor = 1;
                for (int Dimension = 1; Dimension < Entry.Value.DimensionCount; Dimension++)
                {
                    int ThisDimensionLength = BaseArray.GetLength(Entry.Value.DimensionCount - 1 - (Dimension - 1));
                    BaseFactor *= ThisDimensionLength;
                    ctx.PutArgument(Entry.Value.ScaleArgument[Dimension], (int)BaseFactor);
                }
            }
            ctx.Complete();

            OpenCLInterop.CallOpenCLNet(WorkSize, CacheEntry, ctx, HLgraph, device);
        }
예제 #7
0
            /// <summary>
            /// Perform data-flow analysis to get dead definitions for each basic block.
            /// </summary>
            /// <param name="Graph">HlGraph.</param>
            /// <returns>Data flow results.</returns>
            /// <remarks>Dead definitions is an all-paths reverse data flow problem described by the
            /// following equations:
            ///
            /// <code>
            /// InitFn(n)       := ( (n == CanonicalExit) ? ALL_STACK | ALL_LOCAL | ALL_ARG : TOP, TOP )
            /// NodeFn(n, l)    := l + n.DAD - n.UEU
            /// EdgeFn(s, t, l) := l
            /// MergeFn(l, r)   := (l &amp; r)
            /// </code>
            /// </remarks>
            public static DataFlow <LocationList> .Result DoDF(HlGraph Graph)
            {
                DataFlow <LocationList> .Result DfResult = DataFlow <LocationList> .Reverse(
                    Graph.BasicBlocks,
                    delegate(BasicBlock BasicBlock, out LocationList Entry, out LocationList Exit)
                {
                    if (Graph.CanonicalExitBlock == BasicBlock)
                    {
                        Entry = new LocationList();
                        for (int i = 0; i < Graph.m_MaxStack; i++)
                        {
                            Entry.Add(new StackLocation(i));
                        }
                        foreach (LocalVariableLocation LocVar in Graph.LocalVariables)
                        {
                            Entry.Add(LocVar);
                        }
                        foreach (ArgumentLocation Arg in Graph.Arguments)
                        {
                            Entry.Add(Arg);
                        }
                        Exit = null;
                    }
                    else
                    {
                        Entry = Exit = null;
                    }
                },
                    delegate(BasicBlock BasicBlock, LocationList DeadDefinitionList)
                {
                    return(BeforeInstruction(BasicBlock, 0, DeadDefinitionList));
                },
                    delegate(BasicBlock Source, BasicBlock Target, LocationList DeadDefinitionList)
                {
                    return(DeadDefinitionList);
                },
                    LocationList.MergeInlineAnd
                    );

                return(DfResult);
            }
예제 #8
0
        internal static void WriteOpenCL(HighLevel.HlGraph HLgraph, Type StructType, TextWriter writer)
        {
            if (StructType == null)
            {
                throw new ArgumentNullException("StructType");
            }
            else if (!StructType.IsValueType)
            {
                throw new ArgumentException(string.Format("Unable to generate OpenCL code for non-ValueType '{0}'", StructType.FullName));
            }

            writer.WriteLine();
            writer.WriteLine("// OpenCL structure definition for type '{0}'", StructType.FullName);
            writer.WriteLine("typedef {0} {{", GetOpenClType(HLgraph, StructType));
            FieldInfo[] Fields = StructType.GetFields();
            foreach (FieldInfo Field in Fields)
            {
                writer.WriteLine("\t{0} {1};", GetOpenClType(HLgraph, Field.FieldType), Field.Name);
            }
            writer.WriteLine("}} t_{0};", HLgraph.ValueTypeMap[StructType]);
        }
예제 #9
0
 public abstract List <HighLevel.Instruction> GetHighLevel(HighLevel.HlGraph Context);
예제 #10
0
        private static HlGraphEntry ConstructHlGraphEntry(MethodInfo Method, int GidParamCount, bool IsKernel, string NameTemplate)
        {
            TextWriter writer     = System.Console.Out;
            string     MethodName = string.Format(NameTemplate, HlGraphSequenceNumber++);

            HighLevel.HlGraph HLgraph = new HighLevel.HlGraph(Method, MethodName);
            HLgraph.IsKernel     = IsKernel;
            HLgraph.ValueTypeMap = m_ValueTypeMap;

            if (!IsKernel && Method.DeclaringType.IsValueType && ((Method.CallingConvention & CallingConventions.HasThis) != 0))
            {
                System.Diagnostics.Debug.Assert(HLgraph.Arguments.Count > 0);
                System.Diagnostics.Debug.Assert(HLgraph.Arguments[0].DataType.IsByRef && HLgraph.Arguments[0].DataType.GetElementType() == Method.DeclaringType);
                HLgraph.KeepThis = true;
            }

            if (DumpCode > 3)
            {
                WriteCode(HLgraph, writer);
            }

            // Optimize it (just some copy propagation and dead assignment elimination to get rid of
            // CIL stack accesses)
            HLgraph.Optimize();

            if (DumpCode > 4)
            {
                WriteCode(HLgraph, writer);
            }

            // Convert all expression trees into something OpenCL can understand
            HLgraph.ConvertForOpenCl(subGraphCache);
            System.Diagnostics.Debug.Assert(HLgraph.KeepThis || !HLgraph.HasThisParameter);

            // Change the real first arguments (the "int"s of the Action<> method) to local variables
            // which get their value from OpenCL's built-in get_global_id() routine.
            // NOTE: ConvertArgumentToLocal removes the specified argument, so both calls need to specify
            //       an ArgumentId of zero!!!
            List <HighLevel.LocalVariableLocation> IdLocation = new List <HighLevel.LocalVariableLocation>();

            for (int i = 0; i < GidParamCount; i++)
            {
                IdLocation.Add(HLgraph.ConvertArgumentToLocal(0));
            }

            // Add fromInclusive and toExclusive as additional parameters
            List <HighLevel.ArgumentLocation> StartIdLocation = new List <HighLevel.ArgumentLocation>();
            List <HighLevel.ArgumentLocation> EndIdLocation   = new List <HighLevel.ArgumentLocation>();

            for (int i = 0; i < GidParamCount; i++)
            {
                StartIdLocation.Add(HLgraph.InsertArgument(i * 2 + 0, "fromInclusive" + i, typeof(int), false));
                EndIdLocation.Add(HLgraph.InsertArgument(i * 2 + 1, "toExclusive" + i, typeof(int), false));
            }

            // "i0 = get_global_id(0) + fromInclusive0;"
            for (int i = 0; i < GidParamCount; i++)
            {
                HLgraph.CanonicalStartBlock.Instructions.Insert(i, new HighLevel.AssignmentInstruction(
                                                                    new HighLevel.LocationNode(IdLocation[i]),
                                                                    new HighLevel.AddNode(
                                                                        new HighLevel.CallNode(typeof(OpenClFunctions).GetMethod("get_global_id", new Type[] { typeof(uint) }), new HighLevel.IntegerConstantNode(i)),
                                                                        new HighLevel.LocationNode(StartIdLocation[i])
                                                                        )
                                                                    )
                                                                );
            }

            // "if (i0 >= toExclusive0) return;"
            if (GidParamCount > 0)
            {
                HighLevel.BasicBlock ReturnBlock = null;
                foreach (HighLevel.BasicBlock BB in HLgraph.BasicBlocks)
                {
                    if (BB.Instructions.Count == 1 && BB.Instructions[0].InstructionType == HighLevel.InstructionType.Return)
                    {
                        ReturnBlock = BB;
                        break;
                    }
                }
                if (ReturnBlock == null)
                {
                    ReturnBlock = new HighLevel.BasicBlock("CANONICAL_RETURN_BLOCK");
                    ReturnBlock.Instructions.Add(new HighLevel.ReturnInstruction(null));
                    HLgraph.BasicBlocks.Add(ReturnBlock);
                }
                ReturnBlock.LabelNameUsed = true;
                for (int i = 0; i < GidParamCount; i++)
                {
                    HLgraph.CanonicalStartBlock.Instructions.Insert(GidParamCount + i, new HighLevel.ConditionalBranchInstruction(
                                                                        new HighLevel.GreaterEqualsNode(
                                                                            new HighLevel.LocationNode(IdLocation[i]),
                                                                            new HighLevel.LocationNode(EndIdLocation[i])
                                                                            ),
                                                                        ReturnBlock
                                                                        )
                                                                    );
                }
            }

            // Create the argument to pass the random seed, if necessary
            if (!object.ReferenceEquals(HLgraph.RandomStateLocation, null) && HLgraph.RandomStateLocation.LocationType == HighLevel.LocationType.LocalVariable)
            {
                // This can only happen for kernels. All nested routines get a pointer to
                // the kernel's rnd_state instead

                System.Diagnostics.Debug.Assert(HLgraph.IsKernel);
                System.Diagnostics.Debug.Assert(object.ReferenceEquals(HLgraph.RandomSeedArgument, null));

                HLgraph.RandomSeedArgument = HLgraph.CreateArgument("rnd_seed", typeof(uint), false);

                if (GidParamCount > 0)
                {
                    HighLevel.Node LocalSeed = null;
                    for (int i = 0; i < GidParamCount; i++)
                    {
                        if (LocalSeed == null)
                        {
                            LocalSeed = new HighLevel.LocationNode(IdLocation[i]);
                        }
                        else
                        {
                            LocalSeed = new HighLevel.AddNode(
                                new HighLevel.LocationNode(IdLocation[i]),
                                new HighLevel.MulNode(
                                    LocalSeed,
                                    new HighLevel.IntegerConstantNode(0x10000)              /* TODO: what is a good factor here ??? */
                                    )
                                );
                        }
                    }
                    HLgraph.CanonicalStartBlock.Instructions.Add(new HighLevel.AssignmentInstruction(
                                                                     new HighLevel.NamedFieldNode(new HighLevel.LocationNode(HLgraph.RandomStateLocation), "x", typeof(uint)),
                                                                     new HighLevel.AddNode(
                                                                         LocalSeed,
                                                                         new HighLevel.IntegerConstantNode(1)
                                                                         )
                                                                     )
                                                                 );
                }
                else
                {
                    HLgraph.CanonicalStartBlock.Instructions.Add(new HighLevel.AssignmentInstruction(
                                                                     new HighLevel.NamedFieldNode(new HighLevel.LocationNode(HLgraph.RandomStateLocation), "x", typeof(uint)),
                                                                     new HighLevel.IntegerConstantNode(1)
                                                                     )
                                                                 );
                }

                HLgraph.CanonicalStartBlock.Instructions.Add(new HighLevel.AssignmentInstruction(
                                                                 new HighLevel.NamedFieldNode(new HighLevel.LocationNode(HLgraph.RandomStateLocation), "y", typeof(uint)),
                                                                 new HighLevel.LocationNode(HLgraph.RandomSeedArgument)
                                                                 ));

                // Perform TWO warmup rounds, so our not-so-random start states
                // get a chance to really inflict changes to all 32 bits of
                // generated random numbers.
                HLgraph.CanonicalStartBlock.Instructions.Add(new HighLevel.AssignmentInstruction(
                                                                 null,
                                                                 new HighLevel.CallNode(
                                                                     typeof(OpenClFunctions).GetMethod("rnd"),
                                                                     new HighLevel.AddressOfNode(
                                                                         new HighLevel.LocationNode(HLgraph.RandomStateLocation)
                                                                         )
                                                                     )
                                                                 )
                                                             );
                HLgraph.CanonicalStartBlock.Instructions.Add(new HighLevel.AssignmentInstruction(
                                                                 null,
                                                                 new HighLevel.CallNode(
                                                                     typeof(OpenClFunctions).GetMethod("rnd"),
                                                                     new HighLevel.AddressOfNode(
                                                                         new HighLevel.LocationNode(HLgraph.RandomStateLocation)
                                                                         )
                                                                     )
                                                                 )
                                                             );
            }

            if (DumpCode > 5)
            {
                WriteCode(HLgraph, writer);
            }

            // Update location usage information
            HLgraph.AnalyzeLocationUsage();

            // Finally, add the graph to the cache
            HlGraphEntry CacheEntry = new HlGraphEntry(HLgraph, StartIdLocation, EndIdLocation);

            return(CacheEntry);
        }
예제 #11
0
        public override string ToString()
        {
            StringBuilder String = new StringBuilder();
            int           i      = 0;

            if (!IsStaticCall)
            {
                if (SubNodes.Count == 0)
                {
                    String.Append("(???).");
                }
                else
                {
                    String.Append(SubNodes[0].ToString());
                    String.Append(".");
                }
                i++;
            }

            string Name = object.ReferenceEquals(HlGraph, null) ? OpenClAliasAttribute.Get(MethodInfo) : HlGraph.GetOpenClFunctionName(MethodInfo);

            if (Name == null)
            {
                Name = MethodInfo.Name;
            }
            String.Append(Name);
            String.Append("(");

            bool IsFirst = true;

            for (; i < SubNodes.Count; i++)
            {
                if (IsFirst)
                {
                    IsFirst = false;
                }
                else
                {
                    String.Append(", ");
                }
                String.Append(SubNodes[i].ToString());
            }

            String.Append(")");

            return(String.ToString());
        }
예제 #12
0
        private static void GenerateOpenCLSource(HlGraphEntry CacheEntry)
        {
            // Non-kernel methods include just their own code, but kernel methods include everything required
            if (!CacheEntry.HlGraph.IsKernel || CacheEntry.HlGraph.RelatedGraphs.Count == 0)
            {
                CacheEntry.Source = getOpenCLSource(CacheEntry.HlGraph);
                return;
            }

            // No recursion allowed, so we can get away with a topological sort of all involved functions
            // with no prototypes beforehand.
            // The following code has been adapted from
            // http://www.logarithmic.net/pfh-files/blog/01208083168/sort.py
            // "Tarjan's algorithm and topological sorting implementation in Python" by Paul Harrison

            // Step 1: get list of all involved methods
            List <HighLevel.HlGraph> Nodes = new List <HighLevel.HlGraph>();

            Nodes.Add(CacheEntry.HlGraph);
            for (int i = 0; i < Nodes.Count; i++)
            {
                HighLevel.HlGraph Entry = Nodes[i];
                foreach (HlGraphEntry SubEntry in Entry.RelatedGraphs.Values)
                {
                    if (!Nodes.Contains(SubEntry.HlGraph))
                    {
                        Nodes.Add(SubEntry.HlGraph);
                    }
                }
            }

            // Step 2: topological sort
            Dictionary <HighLevel.HlGraph, int> count = new Dictionary <HighLevel.HlGraph, int>();

            foreach (HighLevel.HlGraph Current in Nodes)
            {
                count[Current] = 0;
            }
            foreach (HighLevel.HlGraph Current in Nodes)
            {
                foreach (HlGraphEntry SuccessorEntry in Current.RelatedGraphs.Values)
                {
                    count[SuccessorEntry.HlGraph]++;
                }
            }

            List <HighLevel.HlGraph> Ready  = new List <HighLevel.HlGraph>();
            List <HighLevel.HlGraph> Result = new List <HighLevel.HlGraph>(Nodes.Count);

            Ready.Add(CacheEntry.HlGraph);
            while (Ready.Count > 0)
            {
                HighLevel.HlGraph Current = Ready[Ready.Count - 1];
                Ready.RemoveAt(Ready.Count - 1);
                Result.Add(Current);
                System.Diagnostics.Debug.Assert(count[Current] == 0);

                foreach (HlGraphEntry Successor in Current.RelatedGraphs.Values)
                {
                    count[Successor.HlGraph]--;
                    if (count[Successor.HlGraph] == 0)
                    {
                        Ready.Add(Successor.HlGraph);
                    }
                }
            }

            // Step 3: check for recursions. If there is any strongly-connected component, count[s]
            // will never reach zero, so the Ready list runs empty without all functions being
            // inserted into the Result list.
            if (Result.Count != Nodes.Count)
            {
                throw new InvalidOperationException("Unable to compute topological sort of functions. Recursions are not supported.");
            }

            // Generate code for all HlGraphs in the Result list, in reverse order
            Result.Reverse();

            CacheEntry.Source = getOpenCLSource(Result);
        }
예제 #13
0
 public InvokeContext(HighLevel.HlGraph HLgraph)
     : this(HLgraph, GetRandomSeed())
 {
 }
예제 #14
0
 public static string GetOpenClType(HighLevel.HlGraph HlGraph, Type DataType)
 {
     return(InnerGetOpenClType(HlGraph, DataType));
 }
예제 #15
0
 private static string InnerGetOpenClType(HighLevel.HlGraph HlGraph, Type DataType)
 {
     if (DataType == typeof(void))
     {
         return("void");
     }
     else if (DataType == typeof(sbyte))
     {
         return("char");
     }
     else if (DataType == typeof(byte))
     {
         return("uchar");
     }
     else if (DataType == typeof(short))
     {
         return("short");
     }
     else if (DataType == typeof(ushort))
     {
         return("ushort");
     }
     else if (DataType == typeof(int) || DataType == typeof(IntPtr) || DataType == typeof(bool))
     {
         return("int");
     }
     else if (DataType == typeof(uint) || DataType == typeof(UIntPtr))
     {
         return("uint");
     }
     else if (DataType == typeof(long))
     {
         return("long");
     }
     else if (DataType == typeof(ulong))
     {
         return("ulong");
     }
     else if (DataType == typeof(float))
     {
         return("float");
     }
     else if (DataType == typeof(double))
     {
         return("double");
     }
     else if (DataType.IsByRef)
     {
         return(InnerGetOpenClType(HlGraph, DataType.GetElementType()) + "*");
     }
     else if (DataType.IsArray)
     {
         return(InnerGetOpenClType(HlGraph, DataType.GetElementType()) + "*");
     }
     else if (object.ReferenceEquals(DataType, RandomStateDataType))
     {
         return("uint2");
     }
     else if (DataType.IsValueType && DataType.BaseType == typeof(System.ValueType) && HlGraph != null && HlGraph.ValueTypeMap != null)
     {
         string Name;
         if (!HlGraph.ValueTypeMap.TryGetValue(DataType, out Name))
         {
             HlGraph.ValueTypeMap[DataType] = Name = "genstruct_" + HlGraph.ValueTypeMap.Count;
         }
         return("struct " + Name);
     }
     else
     {
         throw new ArgumentException(string.Format("Sorry, data type '{0}' cannot be mapped to OpenCL.", DataType));
     }
 }
예제 #16
0
        internal static void CallOpenCLNet(int[] WorkSize, HlGraphEntry CacheEntry, InvokeContext ctx, HighLevel.HlGraph HLgraph, OpenCLNet.Device device)
        {
            // We can invoke the kernel using the arguments from ctx now :)
            if (device == null)
            {
                device = GetFirstGpu();
                if (device == null)
                {
                    device = GetFirstCpu();
                }
                if (device == null)
                {
                    throw new ArgumentNullException("device");
                }
            }

            OpenCLNet.Platform Platform = device.Platform;

            OpenCLNet.Context context;
            OpenCLNet.Program program;

            lock (CacheEntry)
            {
                context = CacheEntry.Context;
                if (context == null)
                {
                    IntPtr[] properties = new IntPtr[]
                    {
                        new IntPtr((long)OpenCLNet.ContextProperties.PLATFORM), Platform.PlatformID,
                        IntPtr.Zero,
                    };
                    context = CacheEntry.Context = Platform.CreateContext(properties, new OpenCLNet.Device[] { device }, null, IntPtr.Zero);
                }

                program = CacheEntry.Program;
                if (program == null)
                {
                    StringBuilder source = new StringBuilder();
                    source.Append(GetOpenCLSourceHeader(Platform, device, CacheEntry));
                    source.Append(CacheEntry.Source);
                    source.Append(GetOpenCLSourceFooter(Platform, device));

                    program = context.CreateProgramWithSource(source.ToString());

                    try
                    {
                        program.Build();
                    }
                    catch (Exception ex)
                    {
                        string err = program.GetBuildLog(device);
                        throw new Exception(err, ex);
                    }

                    CacheEntry.Program = program;
                }
            }

            using (CallContext CallContext = new CallContext(context, device, OpenCLNet.CommandQueueProperties.PROFILING_ENABLE, program.CreateKernel(HLgraph.MethodName)))
            {
                OpenCLNet.CommandQueue commandQueue = CallContext.CommandQueue;

                for (int i = 0; i < ctx.Arguments.Count; i++)
                {
                    ctx.Arguments[i].WriteToKernel(CallContext, i);
                }

                //OpenCLNet.Event StartEvent, EndEvent;

                //commandQueue.EnqueueMarker(out StartEvent);

                IntPtr[] GlobalWorkSize = new IntPtr[WorkSize.Length];
                for (int i = 0; i < WorkSize.Length; i++)
                {
                    GlobalWorkSize[i] = new IntPtr(WorkSize[i]);
                }
                commandQueue.EnqueueNDRangeKernel(CallContext.Kernel, (uint)GlobalWorkSize.Length, null, GlobalWorkSize, null);

                for (int i = 0; i < ctx.Arguments.Count; i++)
                {
                    ctx.Arguments[i].ReadFromKernel(CallContext, i);
                }

                commandQueue.Finish();
                //commandQueue.EnqueueMarker(out EndEvent);
                //commandQueue.Finish();

                //ulong StartTime, EndTime;
                //StartEvent.GetEventProfilingInfo(OpenCLNet.ProfilingInfo.QUEUED, out StartTime);
                //EndEvent.GetEventProfilingInfo(OpenCLNet.ProfilingInfo.END, out EndTime);
            }
        }
예제 #17
0
        internal static void WriteOpenCL(HighLevel.HlGraph HLgraph, TextWriter writer)
        {
            writer.WriteLine();
            writer.WriteLine("// OpenCL source for {2} method '{0}' of type '{1}'", HLgraph.MethodBase.ToString(), HLgraph.MethodBase.DeclaringType.ToString(), HLgraph.IsKernel ? "kernel" : "related");
            writer.WriteLine("{2}{0} {1}(", GetOpenClType(HLgraph, ((MethodInfo)HLgraph.MethodBase).ReturnType), HLgraph.MethodName, HLgraph.IsKernel ? "__kernel " : string.Empty);
            for (int i = 0; i < HLgraph.Arguments.Count; i++)
            {
                HighLevel.ArgumentLocation Argument = HLgraph.Arguments[i];

                string AttributeString = string.Empty;
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectRead) != 0)
                {
                    AttributeString += "/*[in";
                }
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectWrite) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[out";
                    }
                    else
                    {
                        AttributeString += ",out";
                    }
                }

                if (AttributeString != string.Empty)
                {
                    AttributeString += "]*/ ";
                }

                if ((Argument.DataType.IsArray || Argument.DataType.IsPointer || Argument.DataType.IsByRef) &&
                    ((Argument.Flags & Hybrid.MsilToOpenCL.HighLevel.LocationFlags.PointerLocal) == 0))
                {
                    AttributeString += "__global ";
                }

                writer.WriteLine("\t{0}{1} {2}{3}", AttributeString, GetOpenClType(HLgraph, Argument.DataType), Argument.Name, i + 1 < HLgraph.Arguments.Count ? "," : string.Empty);
            }
            writer.WriteLine(")");
            writer.WriteLine("/*");
            writer.WriteLine("  Generated by CIL2OpenCL");
            writer.WriteLine("*/");
            writer.WriteLine("{");

            foreach (HighLevel.LocalVariableLocation LocalVariable in HLgraph.LocalVariables)
            {
                string AttributeString = string.Empty;
                if ((LocalVariable.Flags & HighLevel.LocationFlags.Read) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "read";
                }
                if ((LocalVariable.Flags & HighLevel.LocationFlags.Write) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "write";
                }
                if ((LocalVariable.Flags & HighLevel.LocationFlags.IndirectRead) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "deref_read";
                }
                if ((LocalVariable.Flags & HighLevel.LocationFlags.IndirectWrite) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "deref_write";
                }
                if (AttributeString == string.Empty)
                {
                    AttributeString = "/*UNUSED*/ // ";
                }
                else
                {
                    AttributeString += "]*/ ";
                }
                if ((LocalVariable.Flags & Hybrid.MsilToOpenCL.HighLevel.LocationFlags.PointerGlobal) != 0)
                {
                    AttributeString += "__global ";
                }

                writer.WriteLine("\t{0}{1} {2};", AttributeString, GetOpenClType(HLgraph, LocalVariable.DataType), LocalVariable.Name);
            }

            HighLevel.BasicBlock FallThroughTargetBlock = HLgraph.CanonicalStartBlock;
            for (int i = 0; i < HLgraph.BasicBlocks.Count; i++)
            {
                HighLevel.BasicBlock BB = HLgraph.BasicBlocks[i];

                if (BB == HLgraph.CanonicalEntryBlock || BB == HLgraph.CanonicalExitBlock)
                {
                    continue;
                }

                if (FallThroughTargetBlock != null && FallThroughTargetBlock != BB)
                {
                    writer.WriteLine("\tgoto {0};", FallThroughTargetBlock.LabelName);
                }

                FallThroughTargetBlock = null;

                writer.WriteLine();
                if (BB.LabelNameUsed)
                {
                    writer.WriteLine("{0}:", BB.LabelName);
                }
                else
                {
                    writer.WriteLine("//{0}: (unreferenced block label)", BB.LabelName);
                }

                foreach (HighLevel.Instruction Instruction in BB.Instructions)
                {
                    writer.WriteLine("\t{0}", Instruction.ToString());
                }

                if (BB.Successors.Count == 0)
                {
                    writer.WriteLine("\t// End of block is unreachable");
                }
                else if (BB.Successors[0] == HLgraph.CanonicalExitBlock)
                {
                    writer.WriteLine("\t// End of block is unreachable/canonical routine exit");
                }
                else
                {
                    FallThroughTargetBlock = BB.Successors[0];
                }
            }

            writer.WriteLine("}");
        }
예제 #18
0
        private static void WriteCode(HighLevel.HlGraph HLgraph, TextWriter writer)
        {
            writer.WriteLine("// begin {0}", HLgraph.MethodBase);

            if (HLgraph.MethodBase.IsConstructor)
            {
                writer.Write("constructor {0}::{1} (", ((System.Reflection.ConstructorInfo)HLgraph.MethodBase).DeclaringType, HLgraph.MethodBase.Name);
            }
            else
            {
                writer.Write("{0} {1}(", ((MethodInfo)HLgraph.MethodBase).ReturnType, HLgraph.MethodBase.Name);
            }

            for (int i = 0; i < HLgraph.Arguments.Count; i++)
            {
                if (i > 0)
                {
                    writer.Write(", ");
                }

                HighLevel.ArgumentLocation Argument = HLgraph.Arguments[i];
                string AttributeString = string.Empty;
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectRead) != 0)
                {
                    AttributeString += "__deref_read ";
                }
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectWrite) != 0)
                {
                    AttributeString += "__deref_write ";
                }

                writer.Write("{0}{1} {2}", AttributeString, Argument.DataType, Argument.Name);
            }

            writer.WriteLine(") {");

            foreach (HighLevel.LocalVariableLocation LocalVariable in HLgraph.LocalVariables)
            {
                writer.WriteLine("\t{0} {1};", LocalVariable.DataType, LocalVariable.Name);
            }

            for (int i = 0; i < HLgraph.BasicBlocks.Count; i++)
            {
                HighLevel.BasicBlock BB = HLgraph.BasicBlocks[i];

                if (BB == HLgraph.CanonicalEntryBlock || BB == HLgraph.CanonicalExitBlock)
                {
                    continue;
                }

                writer.WriteLine();
                writer.WriteLine("{0}:", BB.LabelName);
                foreach (HighLevel.Instruction Instruction in BB.Instructions)
                {
                    writer.WriteLine("\t{0}", Instruction.ToString());
                }

                if (BB.Successors.Count == 0)
                {
                    writer.WriteLine("\t// unreachable code");
                }
                else if (i + 1 == HLgraph.BasicBlocks.Count || HLgraph.BasicBlocks[i + 1] != BB.Successors[0])
                {
                    if (BB.Successors[0] == HLgraph.CanonicalExitBlock)
                    {
                        writer.WriteLine("\t// to canonical routine exit");
                    }
                    else
                    {
                        writer.WriteLine("\tgoto {0};", BB.Successors[0].LabelName);
                    }
                }
            }

            writer.WriteLine("}");
            writer.WriteLine("// end");
            writer.WriteLine();
        }
예제 #19
0
            private void TraverseTree(Node Node, bool TopIsDef, bool ArrayDef)
            {
                if (Node == null)
                {
                    return;
                }

                if (TopIsDef)
                {
                    if (Node.NodeType == NodeType.Location)
                    {
                        Location Location = ((LocationNode)Node).Location;
                        if (!DefinedLocations.Contains(Location))
                        {
                            DefinedLocations.Add(Location);
                        }
                    }
                    else if (Node.NodeType == NodeType.ArrayAccess)
                    {
                        TraverseTree(Node, false, true);
                    }
                    else if (Node.NodeType == NodeType.AddressOf)
                    {
                        TraverseTree(((AddressOfNode)Node).SubNodes[0], true, false);
                        TraverseTree(((AddressOfNode)Node).SubNodes[0], false, false);
                    }
                    else if (Node.NodeType == NodeType.Deref)
                    {
                        TraverseTree(((DerefNode)Node).SubNodes[0], false, false);
                    }
                    else if (Node.NodeType == NodeType.InstanceField)
                    {
                        // Do nothing here. ConvertForOpenCl will convert this to an argument location,
                        // so regular analysis treats it as such at a later pass
                    }
                    else if (Node.NodeType == NodeType.NamedField)
                    {
                        TraverseTree(((NamedFieldNode)Node).SubNodes[0], true, false);
                    }
                    else
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
                else
                {
                    if (Node.NodeType == NodeType.Location)
                    {
                        Location Location = ((LocationNode)Node).Location;
                        if (!UsedLocations.Contains(Location))
                        {
                            UsedLocations.Add(Location);
                        }
                    }
                    else
                    {
                        HlGraphEntry RelatedGraphEntry;

                        if (Node.NodeType == NodeType.ArrayAccess && Node.SubNodes.Count > 0 && Node.SubNodes[0].NodeType == NodeType.Location)
                        {
                            Location ArrayLocation = ((LocationNode)Node.SubNodes[0]).Location;

                            if (ArrayDef && !IndirectDefinedLocations.Contains(ArrayLocation))
                            {
                                IndirectDefinedLocations.Add(ArrayLocation);
                            }
                            else if (!ArrayDef && !IndirectUsedLocations.Contains(ArrayLocation))
                            {
                                IndirectUsedLocations.Add(ArrayLocation);
                            }
                        }
                        else if (Node.NodeType == NodeType.Call && Node.SubNodes.Count > 0 && !object.ReferenceEquals(RelatedGraphs, null) &&
                                 RelatedGraphs.TryGetValue(((CallNode)Node).MethodInfo, out RelatedGraphEntry))
                        {
                            // Call to other generated method. Propagate indirect usage flags

                            HlGraph HlGraph = RelatedGraphEntry.HlGraph;

                            for (int i = 0; i < Math.Min(Node.SubNodes.Count, HlGraph.Arguments.Count); i++)
                            {
                                ArgumentLocation Argument = HlGraph.Arguments[i];

                                if ((Argument.Flags & (LocationFlags.IndirectRead | LocationFlags.IndirectWrite)) != 0)
                                {
                                    Node SubNode = Node.SubNodes[i];
                                    if (SubNode.NodeType == NodeType.Location)
                                    {
                                        Location ArrayLocation = ((LocationNode)SubNode).Location;
                                        if ((Argument.Flags & LocationFlags.IndirectRead) != 0 && !IndirectUsedLocations.Contains(ArrayLocation))
                                        {
                                            IndirectUsedLocations.Add(ArrayLocation);
                                        }
                                        if ((Argument.Flags & LocationFlags.IndirectWrite) != 0 && !IndirectDefinedLocations.Contains(ArrayLocation))
                                        {
                                            IndirectDefinedLocations.Add(ArrayLocation);
                                        }
                                    }
                                }
                            }
                        }

                        foreach (Node SubNode in Node.SubNodes)
                        {
                            TraverseTree(SubNode, (SubNode.NodeType == NodeType.AddressOf) ? true : false, false);
                        }
                    }
                }
            }
예제 #20
0
            /// <summary>
            /// Perform intra-block copy propagation.
            /// </summary>
            /// <param name="Graph">HlGraph.</param>
            /// <returns>TRUE if any changes have occured, FALSE otherwise.</returns>
            public static bool Do(HlGraph Graph)
            {
                bool    Changed = false;
                CpState State   = new CpState();
                Dictionary <Location, LocDef> InsertedDict = new Dictionary <Location, LocDef>();
                List <Location> RemoveKeys = new List <Location>();
                List <KeyValuePair <Location, LocDef> > NewDefs = new List <KeyValuePair <Location, LocDef> >();

                //
                // Get the list of undefined locations at the end of each basic block
                //

                DataFlow <LocationList> .Result DfResult = DeadAssignmentElimination.DoDF(Graph);

                //
                // Iterate through basic blocks
                //

                foreach (BasicBlock BB in Graph.BasicBlocks)
                {
                    //
                    // Iterate through instructions
                    //

                    State.Defs.Clear();
                    for (int InstructionIndex = 0; InstructionIndex < BB.Instructions.Count; InstructionIndex++)
                    {
                        Instruction Instruction = BB.Instructions[InstructionIndex];

                        //
                        // Query lists of used and defined locations for the current instruction. If it uses
                        // a location that is present in the CpState, the definition can only be pasted if:
                        //
                        // 1) The definition is not of the form "x := f(..., x, ...)"; i.e., the location
                        //    does not depend on an equally-named one at the defining site,
                        //
                        // OR
                        //
                        // 2) The definition is of the form "x := f(..., x, ...)", and the definition is dead after
                        //    the current instruction.
                        //
                        // NOTE: Pasting the definition in case (2) duplicates evaluation of "f" at the current
                        // instruction, as dead assignment elimination will not be able to remove the original
                        // defining site due to location x being used here. Therefore, in this case, we need to
                        // remove the instruction itself if the definition is pasted, but we can only do so if the
                        // value is not used afterwards.
                        //

                        LocationUsage LocationUsage = LocationUsage.ForInstruction(Instruction);

                        foreach (Location Location in LocationUsage.UsedLocations)
                        {
                            LocDef LocDef;
                            if (State.Defs.TryGetValue(Location, out LocDef) && LocDef.SelfRef)
                            {
                                LocationList DeadList = DeadAssignmentElimination.BeforeInstruction(BB, InstructionIndex + 1, DfResult.ExitState[BB]);
                                if (!DeadList.Contains(Location))
                                {
                                    State.Defs.Remove(Location);
                                }
                            }
                        }

                        //
                        // Rewrite trees
                        //

                        Instruction.Argument = ForTree(BB, Instruction, State, Instruction.Argument, false, ref Changed, InsertedDict);
                        Instruction.Result   = ForTree(BB, Instruction, State, Instruction.Result, true, ref Changed, InsertedDict);

                        //
                        // Change CpState to reflect any newly defined locations
                        //

                        foreach (Location Location in LocationUsage.DefinedLocations)
                        {
                            State.Defs.Remove(Location);
                            if (Location.LocationType == LocationType.CilStack || Location.LocationType == LocationType.LocalVariable)
                            {
                                System.Diagnostics.Debug.Assert(Instruction.InstructionType == InstructionType.Assignment);

                                if (Instruction.Result != null && Instruction.Result.NodeType == NodeType.Location)
                                {
                                    LocDef NewLocDef = new LocDef(BB, Instruction, Location, Instruction.Argument);
                                    NewDefs.Add(new KeyValuePair <Location, LocDef>(Location, NewLocDef));
                                }
                            }

                            //
                            // Remove other definition entries that have been invalidated by redefining one of their inputs
                            //

                            foreach (KeyValuePair <Location, LocDef> Entry in State.Defs)
                            {
                                if (Entry.Value.UsedLocations.Contains(Location))
                                {
                                    RemoveKeys.Add(Entry.Key);
                                }
                            }
                        }

                        //
                        // Remove and add entries to CpState as necessary
                        //

                        if (RemoveKeys != null && RemoveKeys.Count != 0)
                        {
                            foreach (Location RemoveLocation in RemoveKeys)
                            {
                                State.Defs.Remove(RemoveLocation);
                            }
                            RemoveKeys.Clear();
                        }

                        if (NewDefs != null && NewDefs.Count != 0)
                        {
                            foreach (KeyValuePair <Location, LocDef> Entry in NewDefs)
                            {
                                State.Defs.Add(Entry.Key, Entry.Value);
                            }
                            NewDefs.Clear();
                        }

                        //
                        // Remove instructions at defining sites that have become obsolete. This is only
                        // true for CilStack locations, as they are the only ones guaranteed to be consumed
                        // at most once. All other obsolete instructions are taken care of by dead code
                        // elimination.
                        //
                        // BUGBUG: this fails for the DUP instruction...
                        //

                        if (InsertedDict.Count != 0 && LocationUsage.UsedLocations.Count != 0)
                        {
                            foreach (Location Location in LocationUsage.UsedLocations)
                            {
                                LocDef RemoveLocDef;
                                if (Location.LocationType == LocationType.CilStack && InsertedDict.TryGetValue(Location, out RemoveLocDef))
                                {
                                    bool OK = RemoveLocDef.BasicBlock.Instructions.Remove(RemoveLocDef.Instruction);

                                    //System.Diagnostics.Debug.Assert(OK);
                                    System.Diagnostics.Debug.Assert(object.ReferenceEquals(RemoveLocDef.BasicBlock, BB));
                                    if (object.ReferenceEquals(RemoveLocDef.BasicBlock, BB) && OK)
                                    {
                                        System.Diagnostics.Debug.Assert(object.ReferenceEquals(BB.Instructions[InstructionIndex - 1], Instruction));
                                        InstructionIndex--;
                                    }
                                }
                            }
                        }
                        InsertedDict.Clear();
                    }
                }

                return(Changed);
            }