Example #1
0
 /// <summary>
 /// Constructs a new kernel key.
 /// </summary>
 /// <param name="entry">The entry point description.</param>
 /// <param name="specialization">The kernel specialization.</param>
 public CachedCompiledKernelKey(
     EntryPointDescription entry,
     KernelSpecialization specialization)
 {
     Entry          = entry;
     Specialization = specialization;
 }
Example #2
0
        /// <summary>
        /// Compiles the given method into a <see cref="CompiledKernel"/> using the given
        /// kernel specialization.
        /// </summary>
        /// <param name="method">The method to compile into a <see cref="CompiledKernel"/>.</param>
        /// <param name="specialization">The kernel specialization.</param>
        /// <returns>The compiled kernel.</returns>
        public CompiledKernel CompileKernel(MethodInfo method, KernelSpecialization specialization)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            // Check for compatiblity
            if (!specialization.IsCompatibleWith(this))
            {
                throw new NotSupportedException(RuntimeErrorMessages.NotSupportedKernelSpecialization);
            }

            // Check and update cache
            var cachedKey = new CachedCompiledKernelKey(method, specialization);

            lock (syncRoot)
            {
                if (!compiledKernelCache.TryGetValue(cachedKey, out WeakReference <CompiledKernel> cached) ||
                    !cached.TryGetTarget(out CompiledKernel result))
                {
                    result = Backend.Compile(CompileUnit, method, specialization);
                    if (cached == null)
                    {
                        compiledKernelCache.Add(cachedKey, new WeakReference <CompiledKernel>(result));
                    }
                    else
                    {
                        cached.SetTarget(result);
                    }
                }
                RequestGC_SyncRoot();
                return(result);
            }
        }
Example #3
0
        private Kernel LoadGenericKernel <TKernelLoader>(
            MethodInfo method,
            KernelSpecialization specialization,
            ref TKernelLoader kernelLoader)
            where TKernelLoader : struct, IKernelLoader
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }
            var cachedCompiledKernelKey = new CachedCompiledKernelKey(method, specialization);
            var cachedKey = new CachedKernelKey(cachedCompiledKernelKey, kernelLoader.GroupSize);

            lock (syncRoot)
            {
                if (!kernelCache.TryGetValue(cachedKey, out CachedKernel cached) ||
                    !cached.TryGetKernel(out Kernel result))
                {
                    var compiledKernel = CompileKernel(method, specialization);
                    result = kernelLoader.LoadKernel(this, compiledKernel);
                    kernelCache[cachedKey] = new CachedKernel(
                        cached.UpdateReference(result),
                        kernelLoader.GroupSize,
                        kernelLoader.MinGridSize);
                }
                else
                {
                    kernelLoader.MinGridSize = cached.MinGridSize;
                    kernelLoader.GroupSize   = cached.GroupSize;
                }
                RequestGC_SyncRoot();
                return(result);
            }
        }
Example #4
0
        /// <summary>
        /// Loads the given kernel and returns a launcher delegate that
        /// can receive arbitrary accelerator streams (first parameter).
        /// </summary>
        /// <typeparam name="TDelegate">The delegate type.</typeparam>
        /// <param name="method">The method to compile into a kernel.</param>
        /// <param name="specialization">The kernel specialization.</param>
        /// <returns>The loaded kernel-launcher delegate.</returns>
        /// <remarks>
        /// Note that implictly-grouped kernels will be launched with a group size
        /// of the current warp size of the accelerator.
        /// </remarks>
        public TDelegate LoadKernel <TDelegate>(MethodInfo method, KernelSpecialization specialization)
            where TDelegate : class
        {
            var loader = DefaultKernelLoader.Default;

            return(LoadGenericKernel <TDelegate, DefaultKernelLoader>(
                       method,
                       specialization,
                       ref loader));
        }
Example #5
0
        private Kernel LoadGenericKernelDirect <TKernelLoader>(
            MethodInfo method,
            KernelSpecialization specialization,
            ref TKernelLoader kernelLoader)
            where TKernelLoader : struct, IKernelLoader
        {
            var compiledKernel = CompileKernel(method, specialization);

            return(kernelLoader.LoadKernel(this, compiledKernel));
        }
Example #6
0
        private TDelegate LoadGenericKernel <TDelegate, TKernelLoader>(
            MethodInfo method,
            KernelSpecialization specialization,
            ref TKernelLoader kernelLoader)
            where TDelegate : class
            where TKernelLoader : struct, IKernelLoader
        {
            var kernel = LoadGenericKernel(method, specialization, ref kernelLoader);

            return(kernel.CreateLauncherDelegate <TDelegate>());
        }
Example #7
0
        /// <summary>
        /// Loads the given kernel and returns a launcher delegate that launches
        /// the loaded kernel with the default stream.
        /// </summary>
        /// <typeparam name="TDelegate">The delegate type.</typeparam>
        /// <param name="method">The method to compile into a kernel.</param>
        /// <param name="specialization">The kernel specialization.</param>
        /// <returns>The loaded kernel-launcher delegate.</returns>
        /// <remarks>
        /// Note that implictly-grouped kernels will be launched with a group size
        /// of the current warp size of the accelerator.
        /// </remarks>
        public TDelegate LoadStreamKernel <TDelegate>(MethodInfo method, KernelSpecialization specialization)
            where TDelegate : class
        {
            var loader   = DefaultKernelLoader.Default;
            var launcher = new DefaultStreamLauncherProvider();

            return(LoadGenericKernel <TDelegate, DefaultKernelLoader, DefaultStreamLauncherProvider>(
                       method,
                       specialization,
                       ref loader,
                       ref launcher));
        }
Example #8
0
        private TDelegate LoadGenericKernel <TDelegate, TKernelLoader, TLauncherProvider>(
            MethodInfo method,
            KernelSpecialization specialization,
            ref TKernelLoader kernelLoader,
            ref TLauncherProvider launcherProvider)
            where TDelegate : class
            where TKernelLoader : struct, IKernelLoader
            where TLauncherProvider : struct, ILauncherProvider
        {
            var kernel = LoadGenericKernel(method, specialization, ref kernelLoader);

            return(launcherProvider.CreateLauncher <TDelegate>(kernel));
        }
Example #9
0
 /// <summary>
 /// Constructs a new specialization cache.
 /// </summary>
 /// <param name="accelerator">The parent accelerator.</param>
 /// <param name="kernelMethod">The IR kernel method.</param>
 /// <param name="loader">The loader instance.</param>
 /// <param name="entry">The associated entry point.</param>
 /// <param name="specialization">The kernel specialization.</param>
 public SpecializationCache(
     Accelerator accelerator,
     Method kernelMethod,
     TLoader loader,
     EntryPointDescription entry,
     KernelSpecialization specialization)
 {
     Accelerator          = accelerator;
     KernelMethod         = kernelMethod;
     Loader               = loader;
     Entry                = entry;
     KernelSpecialization = specialization;
 }
Example #10
0
        /// <summary>
        /// Loads the given kernel. Implictly-grouped kernels will be launched
        /// with a group size of the current warp size of the accelerator.
        /// </summary>
        /// <param name="method">The method to compile into a kernel.</param>
        /// <param name="specialization">The kernel specialization.</param>
        /// <returns>The loaded kernel.</returns>
        /// <remarks>Note that the returned kernel must not be disposed manually.</remarks>
        public Kernel LoadKernel(MethodInfo method, KernelSpecialization specialization)
        {
            var loader = DefaultKernelLoader.Default;

            return(LoadGenericKernel(method, specialization, ref loader));
        }
Example #11
0
 /// <summary>
 /// Loads the given kernel and returns a launcher delegate that
 /// can receive arbitrary accelerator streams (first parameter).
 /// </summary>
 /// <typeparam name="TSourceDelegate">The source delegate type.</typeparam>
 /// <typeparam name="TDelegate">The delegate type.</typeparam>
 /// <param name="methodDelegate">The delegate to compile into a kernel.</param>
 /// <param name="specialization">The kernel specialization.</param>
 /// <returns>The loaded kernel-launcher delegate.</returns>
 /// <remarks>
 /// Note that implictly-grouped kernels will be launched with a group size
 /// of the current warp size of the accelerator.
 /// </remarks>
 public TDelegate LoadKernel <TDelegate, TSourceDelegate>(
     TSourceDelegate methodDelegate,
     KernelSpecialization specialization)
     where TDelegate : Delegate
     where TSourceDelegate : Delegate =>
 LoadKernel <TDelegate>(methodDelegate.GetMethodInfo(), specialization);
Example #12
0
 /// <summary>
 /// Constructs a new kernel key.
 /// </summary>
 /// <param name="method">The kernel method.</param>
 /// <param name="specialization">The kernel specialization.</param>
 public CachedCompiledKernelKey(MethodInfo method, KernelSpecialization specialization)
 {
     Method         = method;
     Specialization = specialization;
 }