Beispiel #1
0
        /// <summary>
        /// Constructs a new CPU runtime.
        /// </summary>
        /// <param name="context">The ILGPU context.</param>
        /// <param name="numThreads">The number of threads for paralllel processing.</param>
        /// <param name="warpSize">The number of threads per warp.</param>
        /// <param name="threadPriority">The thread priority of the execution threads.</param>
        /// <param name="flags">The compile-unit flags.</param>
        public CPUAccelerator(
            Context context,
            int numThreads,
            int warpSize,
            ThreadPriority threadPriority,
            CompileUnitFlags flags)
            : base(context, AcceleratorType.CPU)
        {
            if (numThreads < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(numThreads));
            }
            if (!CPURuntimeWarpContext.IsValidWarpSize(warpSize) || numThreads < warpSize || (numThreads % warpSize) != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(warpSize));
            }

            // Setup assembly and module builder for dynamic code generation
            var assemblyName = new AssemblyName(nameof(CPUAccelerator));

            assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            moduleBuilder   = assemblyBuilder.DefineDynamicModule(nameof(CPUAccelerator));

            NumThreads    = numThreads;
            WarpSize      = warpSize;
            threads       = new Thread[numThreads];
            finishedEvent = new Barrier(numThreads + 1);
            // Every thread requires a custom warp context.
            warpContexts = new CPURuntimeWarpContext[numThreads];
            // The maximum number of thread groups that can be handled in parallel is
            // equal to the number of available threads in the worst case.
            groupContexts = new CPURuntimeGroupContext[numThreads];
            for (int i = 0; i < numThreads; ++i)
            {
                warpContexts[i]  = new CPURuntimeWarpContext(this);
                groupContexts[i] = new CPURuntimeGroupContext(this);
                var thread = threads[i] = new Thread(ExecuteThread)
                {
                    IsBackground = true,
                    Priority     = threadPriority,
                };
                thread.Name = "ILGPUExecutionThread" + i;
                thread.Start(i);
            }

            DefaultStream                  = CreateStream();
            Name                           = nameof(CPUAccelerator);
            MemorySize                     = long.MaxValue;
            MaxGridSize                    = new Index3(int.MaxValue, int.MaxValue, int.MaxValue);
            MaxNumThreadsPerGroup          = NumThreads;
            MaxSharedMemoryPerGroup        = int.MaxValue;
            MaxConstantMemory              = int.MaxValue;
            NumMultiprocessors             = 1;
            MaxNumThreadsPerMultiprocessor = NumThreads;

            Bind();
            InitBackend(CreateBackend(), flags);
        }
Beispiel #2
0
        /// <summary>
        /// Initializes the internal execution engine.
        /// </summary>
        /// <param name="threadPriority">The desired thread priority.</param>
        private void InitExecutionEngine(ThreadPriority threadPriority)
        {
            threads = new Thread[NumThreads];
            finishedEventPerMultiprocessor = new Barrier(NumMultiprocessors + 1);
            taskConcurrencyLimit           = new SemaphoreSlim(1);

            // Setup all warp and group contexts
            int numWarpsPerMultiprocessor = MaxNumThreadsPerMultiprocessor / WarpSize;

            warpContexts = new CPURuntimeWarpContext[
                NumMultiprocessors,
                numWarpsPerMultiprocessor];
            groupContexts     = new CPURuntimeGroupContext[NumMultiprocessors];
            processorBarriers = new Barrier[NumMultiprocessors];
            for (int i = 0; i < NumMultiprocessors; ++i)
            {
                for (int j = 0; j < numWarpsPerMultiprocessor; ++j)
                {
                    warpContexts[i, j] = new CPURuntimeWarpContext(
                        this,
                        WarpSize);
                }

                groupContexts[i] = UsesSequentialExecution
                    ? new SequentialCPURuntimeGroupContext(this) as CPURuntimeGroupContext
                    : new ParallelCPURuntimeGroupContext(this);
                processorBarriers[i] = new Barrier(0);
            }

            // Instantiate all runtime threads
            Parallel.For(0, NumThreads, i =>
            {
                var thread = threads[i] = new Thread(ExecuteThread)
                {
                    IsBackground = true,
                    Priority     = threadPriority,
                };
                thread.Name = $"ILGPU_{InstanceId}_CPU_{i}";
            });

            // Start or delay the creation of runtime threads
            if (NumThreads <= 32)
            {
                StartOrContinueRuntimeThreads(MaxNumThreadsPerMultiprocessor);
            }
            else
            {
                maxNumLaunchedThreadsPerGroup = 0;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Creates a new CPU multiprocessor.
        /// </summary>
        /// <param name="accelerator">The parent accelerator.</param>
        /// <param name="processorIndex">The index of the multiprocessor.</param>
        protected CPUMultiprocessor(CPUAccelerator accelerator, int processorIndex)
        {
            Accelerator    = accelerator;
            ProcessorIndex = processorIndex;

            // Setup all warp and group contexts
            NumWarpsPerMultiprocessor = MaxNumThreadsPerMultiprocessor / WarpSize;
            warpContexts = new CPURuntimeWarpContext[NumWarpsPerMultiprocessor];
            groupContext = new CPURuntimeGroupContext(this);
            for (int i = 0; i < NumWarpsPerMultiprocessor; ++i)
            {
                warpContexts[i] = new CPURuntimeWarpContext(this, WarpSize);
            }

            // Instantiate all runtime threads
            threads = new Thread[MaxNumThreadsPerMultiprocessor];
            Parallel.For(0, MaxNumThreadsPerMultiprocessor, i =>
            {
                var thread = threads[i] = new Thread(ExecuteThread)
                {
                    IsBackground = true,
                    Priority     = Accelerator.ThreadPriority,
                };
                thread.Name = $"ILGPU_{Accelerator.InstanceId}_CPU_{ProcessorIndex}_{i}";
            });

            // Start or delay the creation of runtime threads
            if (MaxNumThreadsPerMultiprocessor <= 32)
            {
                StartOrContinueRuntimeThreads(MaxNumThreadsPerMultiprocessor);
            }
            else
            {
                maxNumLaunchedThreadsPerGroup = 0;
            }
        }
Beispiel #4
0
 /// <summary>
 /// Makes the current context the active one for this thread.
 /// </summary>
 internal void MakeCurrent()
 {
     currentContext = this;
 }