Example #1
0
        /// <summary>
        /// Compiles a given compile unit with the specified entry point.
        /// </summary>
        /// <param name="unit">The compile unit to compile.</param>
        /// <param name="entry">The desired entry point.</param>
        /// <param name="specialization">The kernel specialization.</param>
        /// <returns>The compiled kernel that represents the compilation result.</returns>
        public override CompiledKernel Compile(
            CompileUnit unit,
            MethodInfo entry,
            KernelSpecialization specialization)
        {
            var entryPoint = new EntryPoint(entry, unit, specialization);

            CheckMethod(unit, entry, entryPoint);
            return(new CompiledKernel(Context, entry, new byte[] { }, entry.Name, entryPoint));
        }
Example #2
0
        /// <summary cref="Backend.Compile(CompileUnit, MethodInfo)"/>
        public override CompiledKernel Compile(CompileUnit unit, MethodInfo entry, KernelSpecialization specialization)
        {
            if (unit == null)
            {
                throw new ArgumentNullException(nameof(unit));
            }
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }

            var entryPoint = new EntryPoint(entry, unit, specialization);
            // Ensure that the entry point is contained in the lib
            var backendEntry = CreateEntry(unit, entryPoint, out string entryPointName);

            PrepareModuleLowering?.Invoke(this, new LLVMBackendEventArgs(unit, unit.LLVMModule));

            var targetModule = CloneModule(unit.LLVMModule);

            try
            {
                // Resolve the cloned version of our entry point
                var targetEntry = GetNamedFunction(targetModule, entryPointName);
                PrepareModule(unit, targetModule, entryPoint, targetEntry);

#if DEBUG
                if (VerifyModule(
                        targetModule,
                        LLVMVerifierFailureAction.LLVMReturnStatusAction,
                        out IntPtr errorMessage).Value != 0)
                {
                    throw new InvalidOperationException(string.Format(
                                                            ErrorMessages.LLVMModuleVerificationFailed, Marshal.PtrToStringAnsi(errorMessage)));
                }
#endif

                RunPassManager(Context.KernelModulePassManager, targetModule);
                KernelModuleLowered?.Invoke(this, new LLVMBackendEventArgs(unit, targetModule));

                var binaryKernelData = Link(targetModule, targetEntry);
                return(new CompiledKernel(Context, entry, binaryKernelData, entryPointName, entryPoint));
            }
            finally
            {
                // Set the entry function to internal linkage
                // to avoid further occurances later on
                SetLinkage(backendEntry, LLVMLinkage.LLVMInternalLinkage);

                DisposeModule(targetModule);
            }
        }
Example #3
0
 /// <summary>
 /// Compiles a given compile unit with the specified entry point using
 /// the given kernel specialization.
 /// </summary>
 /// <param name="unit">The compile unit to compile.</param>
 /// <param name="entry">The desired entry point.</param>
 /// <param name="specialization">The kernel specialization.</param>
 /// <returns>The compiled kernel that represents the compilation result.</returns>
 public abstract CompiledKernel Compile(
     CompileUnit unit,
     MethodInfo entry,
     KernelSpecialization specialization);
Example #4
0
        public static void Main2()
        {
            using (var context = new Context())
            {
                foreach (var acceleratorId in Accelerator.Accelerators)
                {
                    if (acceleratorId.AcceleratorType == AcceleratorType.CPU)
                    {
                        continue;
                    }

                    using (var accelerator = Accelerator.Create(context, acceleratorId))
                    {
                        CompiledKernel compiledKernel;

                        using (Backend b = new CLBackend(context, ILGPU.Runtime.OpenCL.CLAcceleratorVendor.AMD))
                        {
                            MethodInfo           methodInfo = typeof(GPU).GetMethod("PixelKernel");
                            KernelSpecialization spec       = KernelSpecialization.Empty;
                            compiledKernel = b.Compile(EntryPointDescription.FromImplicitlyGroupedKernel(methodInfo), spec);
                            // debug: check kernel.Source for source text
                        }

                        var kernel = accelerator.LoadAutoGroupedKernel(compiledKernel);

                        // var kernel = accelerator.LoadAutoGroupedStreamKernel<Index2, ArrayView2D<FSMUnit>>(MathKernel);
                        // kernel = accelerator.LoadAutoGroupedStreamKernel<Index2, ArrayView2D<Color3>, ArrayView<byte>, ArrayView2D<Neuron>>(PixelKernel);

                        MemoryBuffer2D <Color3> buffer  = accelerator.Allocate <Color3>(pixelMap.GetLength(0), pixelMap.GetLength(1));
                        MemoryBuffer <byte>     buffer2 = accelerator.Allocate <byte>(imageBytes.Length);
                        MemoryBuffer2D <Neuron> buffer3 = accelerator.Allocate <Neuron>(nrn.GetLength(0), nrn.GetLength(1));

                        buffer3.CopyFrom(nrn, new LongIndex2(0, 0), new LongIndex2(0, 0), new LongIndex2(nrn.GetLength(0), nrn.GetLength(1)));

                        while (running == true)
                        {
                            Stopwatch sw = new Stopwatch();
                            sw.Start();

                            Index2 gridSize = new Index2(pixelMap.GetLength(0), pixelMap.GetLength(1));

                            //kernel(gridSize, buffer.View, buffer2.View, buffer3.View);

                            sw.OutputDelta("Kernel");

                            accelerator.Synchronize();

                            sw.OutputDelta("Sync");

                            // imageBytes = buffer2.GetAsArray();
                            buffer2.CopyTo(imageBytes, 0, 0, imageBytes.Length);

                            sw.OutputDelta("Copy ImageBytes");

                            // Resolve and verify data
                            //pixelMap = buffer.GetAs2DArray();
                            // buffer.CopyTo(pixelMap, new LongIndex2(0, 0), new LongIndex2(0, 0), new LongIndex2(pixelMap.GetLength(0), pixelMap.GetLength(1)));

                            // Color3[] pixelMap1D = buffer.GetAsArray();
                            //Copy1DTo2DArray(pixelMap1D, pixelMap); // ~36ms, a bit faster

                            //Array.Copy(pixelMap1D, imageBytes, pixelMap1D.Length); // fails
                            //Buffer.BlockCopy(pixelMap1D, 0, pixelMap, 0, pixelMap1D.Length * Marshal.SizeOf(typeof(Color3))); // fails
                            // pixelMap = Make2DArray(pixelMap1D, pixelMap.GetLength(0), pixelMap.GetLength(1)); // still slow

                            //sw.OutputDelta("Copy PixelMap");

                            // MainForm.form.DrawPixels(pixelMap);
                            MainForm.form.DrawPixels(imageBytes, pixelMap.GetLength(0), pixelMap.GetLength(1));
                            Application.DoEvents();

                            //Debugger.Break();

                            sw.OutputDelta("DrawPixels");
                        }

                        buffer.Dispose();
                        buffer2.Dispose();
                        buffer3.Dispose();

                        Application.Exit();

                        //Debugger.Break();
                    }
                }
            }
        }
Example #5
0
        /// <summary>
        /// Constructs a new entry point targeting the given method.
        /// </summary>
        /// <param name="methodInfo">The targeted method.</param>
        /// <param name="unit">The unit in the current context.</param>
        /// <param name="specialization">The kernel specialization.</param>
        public EntryPoint(
            MethodInfo methodInfo,
            CompileUnit unit,
            KernelSpecialization specialization)
        {
            MethodInfo = methodInfo;
            NumDynamicallySizedSharedMemoryVariables = 0;
            Specialization = specialization;

            if (!methodInfo.IsStatic)
            {
                throw new NotSupportedException(ErrorMessages.InvalidEntryPointInstanceKernelMethod);
            }

            var @params = methodInfo.GetParameters();

            if (@params.Length < 1)
            {
                throw new ArgumentException(ErrorMessages.InvalidEntryPointIndexParameter);
            }
            KernelIndexType = UngroupedIndexType = @params[0].ParameterType;
            Type            = KernelIndexType.GetIndexType();
            if (Type == IndexType.None)
            {
                throw new NotSupportedException(ErrorMessages.InvalidEntryPointIndexParameterOfWrongType);
            }
            UngroupedIndexType = Type.GetUngroupedIndexType().GetManagedIndexType();

            // Compute the number of actual parameters
            var uniformVariables      = new List <UniformVariable>(@params.Length - 1 + (methodInfo.IsStatic ? 1 : 0));
            var sharedMemoryVariables = new List <SharedMemoryVariable>(@params.Length - 1);

            if (!methodInfo.IsStatic)
            {
                uniformVariables.Add(
                    new UniformVariable(0,
                                        methodInfo.DeclaringType.MakePointerType(),
                                        unit.IntPtrType.SizeOf()));
            }
            for (int i = 1, e = @params.Length; i < e; ++i)
            {
                var param = @params[i];
                if (SharedMemoryAttribute.TryGetSharedMemoryCount(param, out int?count))
                {
                    var elementType = GetSharedVariableElementType(param.ParameterType, out bool isArray);
                    var paramSize   = elementType.SizeOf();
                    if (!isArray && count != null && count.Value != 1)
                    {
                        throw new NotSupportedException(ErrorMessages.InvalidUseOfVariableViewsInSharedMemory);
                    }
                    int sharedMemoryVariableIndex = -1;
                    if (isArray && count == null)
                    {
                        sharedMemoryVariableIndex = NumDynamicallySizedSharedMemoryVariables;
                        NumDynamicallySizedSharedMemoryVariables += 1;
                    }
                    sharedMemoryVariables.Add(
                        new SharedMemoryVariable(i,
                                                 sharedMemoryVariableIndex,
                                                 param.ParameterType,
                                                 elementType,
                                                 isArray,
                                                 count,
                                                 paramSize));
                }
                else
                {
                    var paramSize = param.ParameterType.SizeOf();
                    uniformVariables.Add(
                        new UniformVariable(i,
                                            param.ParameterType,
                                            paramSize));
                }
            }

            UniformVariables      = uniformVariables.ToArray();
            SharedMemoryVariables = sharedMemoryVariables.ToArray();

            if (Type < IndexType.GroupedIndex1D && SharedMemoryVariables.Length > 0)
            {
                throw new NotSupportedException(ErrorMessages.NotSupportedUseOfSharedMemory);
            }

            foreach (var variable in uniformVariables)
            {
                if (variable.VariableType != variable.VariableType.GetLLVMTypeRepresentation())
                {
                    throw new NotSupportedException(string.Format(
                                                        ErrorMessages.NotSupportedKernelParameterType, variable));
                }
            }
        }