/// <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; }
/// <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); } }
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); } }
/// <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)); }
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)); }
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>()); }
/// <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)); }
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)); }
/// <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; }
/// <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)); }
/// <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);
/// <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; }