Skip to content

Commit

Permalink
Added support to clear internal caches.
Browse files Browse the repository at this point in the history
See #10.
  • Loading branch information
m4rs-mt committed Mar 1, 2019
1 parent 616fdcc commit cf83683
Show file tree
Hide file tree
Showing 14 changed files with 274 additions and 36 deletions.
11 changes: 10 additions & 1 deletion Src/ILGPU/Backends/ArgumentMapper.cs
Expand Up @@ -27,7 +27,7 @@ namespace ILGPU.Backends
/// can be accessed by the native kernel.
/// </summary>
/// <remarks>Members of this class are not thread safe.</remarks>
public abstract class ArgumentMapper
public abstract class ArgumentMapper : ICache
{
#region Nested Types

Expand Down Expand Up @@ -526,6 +526,15 @@ protected Type MapType(Type type)
}
}

/// <summary>
/// Clears internal caches.
/// </summary>
/// <param name="mode">The clear mode.</param>
public void ClearCache(ClearCacheMode mode)
{
typeMapping.Clear();
}

#endregion
}
}
12 changes: 11 additions & 1 deletion Src/ILGPU/Backends/Backend.cs
Expand Up @@ -43,7 +43,7 @@ public enum TargetPlatform
/// <summary>
/// Represents a general ILGPU backend.
/// </summary>
public abstract class Backend : DisposeBase
public abstract class Backend : DisposeBase, ICache
{
#region Nested Types

Expand Down Expand Up @@ -460,6 +460,16 @@ protected static TargetPlatform GetPlatform(TargetPlatform? platform)
in BackendContext backendContext,
in KernelSpecialization specialization);

/// <summary>
/// Clears all internal caches.
/// </summary>
/// <param name="mode">The clear mode.</param>
/// <remarks>This method is not thread-safe.</remarks>
public void ClearCache(ClearCacheMode mode)
{
ArgumentMapper?.ClearCache(mode);
}

#endregion

#region IDisposable
Expand Down
7 changes: 6 additions & 1 deletion Src/ILGPU/Context.Constants.cs
Expand Up @@ -18,10 +18,15 @@ partial class Context
/// </summary>
public const string RuntimeAssemblyName = "ILGPURuntime";

/// <summary>
/// Represents the general ILGPU assembly name.
/// </summary>
public const string AssemblyName = "ILGPU";

/// <summary>
/// Represents the general ILGPU assembly module name.
/// </summary>
public const string AssemblyModuleName = "ILGPU.dll";
public const string FullAssemblyModuleName = AssemblyName + ".dll";

/// <summary>
/// The ILGPU assembly file extension.
Expand Down
60 changes: 50 additions & 10 deletions Src/ILGPU/Context.cs
Expand Up @@ -32,7 +32,7 @@ namespace ILGPU
/// Represents the main ILGPU context.
/// </summary>
/// <remarks>Members of this class are thread safe.</remarks>
public sealed partial class Context : DisposeBase
public sealed partial class Context : DisposeBase, ICache
{
#region Static

Expand Down Expand Up @@ -129,8 +129,9 @@ static Context()
private PTXContextData ptxContextData;

private readonly object assemblyLock = new object();
private readonly AssemblyBuilder assemblyBuilder;
private readonly ModuleBuilder moduleBuilder;
private int assemblyVersion = 0;
private AssemblyBuilder assemblyBuilder;
private ModuleBuilder moduleBuilder;
private volatile int typeBuilderIdx = 0;

/// <summary>
Expand Down Expand Up @@ -195,13 +196,9 @@ public Context(ContextFlags flags, OptimizationLevel optimizationLevel)
TransformerConfiguration.Transformed,
Flags);

// Initialize assembly and module builder
var assemblyName = new AssemblyName(RuntimeAssemblyName);
assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);

// Initialize context-dependent information
ptxContextData = new PTXContextData(this);
// Initialize assembly builder and context data
ReloadAssemblyBuilder();
ReloadContextData();
}

#endregion
Expand Down Expand Up @@ -257,6 +254,31 @@ public Context(ContextFlags flags, OptimizationLevel optimizationLevel)

#region Methods

/// <summary>
/// Reloads the assembly builder.
/// </summary>
private void ReloadAssemblyBuilder()
{
var assemblyName = new AssemblyName(RuntimeAssemblyName)
{
Version = new Version(1, assemblyVersion++),
};
assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(
assemblyName,
AssemblyBuilderAccess.RunAndCollect);
moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);
}

/// <summary>
/// Reloads context-dependent information.
/// </summary>
private void ReloadContextData()
{
Dispose(ref ptxContextData);

ptxContextData = new PTXContextData(this);
}

/// <summary>
/// Returns true if the current context has the given flags.
/// </summary>
Expand Down Expand Up @@ -346,6 +368,24 @@ public Task<ContextCodeGenerationPhase> BeginCodeGenerationAsync(IRContext irCon
return Task.Run(() => BeginCodeGeneration(irContext));
}

/// <summary>
/// Clears internal caches. However, this does not affect individual accelerator caches.
/// </summary>
/// <param name="mode">The clear mode.</param>
/// <remarks>
/// This method is not thread-safe.
/// </remarks>
public void ClearCache(ClearCacheMode mode)
{
mainContext.ClearCache(mode);
typeContext.ClearCache(mode);
debugInformationManager.ClearCache(mode);
defaultILBackend.ClearCache(mode);

ReloadAssemblyBuilder();
ReloadContextData();
}

#endregion

#region Runtime Assembly
Expand Down
2 changes: 2 additions & 0 deletions Src/ILGPU/ContextFlags.cs
Expand Up @@ -128,6 +128,8 @@ public enum ContextFlags : int
/// <remarks>
/// However, IR nodes, type information and debug information will still
/// be cached, since they are used for different kernel compilation operations.
/// If you want to clear those caches as well, you will have to clear them
/// manually using <see cref="Context.ClearCache(ClearCacheMode)"/>.
/// </remarks>
DisableKernelCaching = 1 << 24,

Expand Down
48 changes: 42 additions & 6 deletions Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs
Expand Up @@ -24,7 +24,7 @@ namespace ILGPU.Frontend.DebugInformation
/// <summary>
/// Represents a debug-information manager.
/// </summary>
public sealed class DebugInformationManager : DisposeBase
public sealed class DebugInformationManager : DisposeBase, ICache
{
#region Constants

Expand Down Expand Up @@ -203,7 +203,7 @@ public bool Load(Assembly assembly, out AssemblyDebugInformation assemblyDebugIn

#region Instance

private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(
private readonly ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(
LockRecursionPolicy.SupportsRecursion);
private readonly Dictionary<string, string> pdbFiles = new Dictionary<string, string>();
private readonly HashSet<string> lookupDirectories = new HashSet<string>();
Expand Down Expand Up @@ -432,6 +432,44 @@ public MethodScopeEnumerator LoadScopes(MethodBase methodBase)
return MethodScopeEnumerator.Empty;
}

/// <summary>
/// Clears cached debug information.
/// </summary>
/// <param name="mode">The clear mode.</param>
public void ClearCache(ClearCacheMode mode)
{
cacheLock.EnterWriteLock();
try
{
if (mode == ClearCacheMode.Everything)
{
foreach (var debugInformation in assemblies.Values)
debugInformation.Dispose();
assemblies.Clear();
}
else
{
// Do not dispose system assemblies
var assembliesToRemove = new List<Assembly>(assemblies.Count);
foreach (var assembly in assemblies.Keys)
{
if (assembly.FullName.StartsWith(Context.AssemblyName, StringComparison.OrdinalIgnoreCase))
continue;
assembliesToRemove.Add(assembly);
}
foreach (var assemblyToRemove in assembliesToRemove)
{
assemblies[assemblyToRemove].Dispose();
assemblies.Remove(assemblyToRemove);
}
}
}
finally
{
cacheLock.ExitWriteLock();
}
}

#endregion

#region IDisposable
Expand All @@ -441,10 +479,8 @@ public MethodScopeEnumerator LoadScopes(MethodBase methodBase)
Justification = "Dispose method will be invoked by a helper method")]
protected override void Dispose(bool disposing)
{
foreach (var assembly in assemblies.Values)
assembly.Dispose();
assemblies.Clear();
Dispose(ref cacheLock);
ClearCache(ClearCacheMode.Everything);
cacheLock.Dispose();
}

#endregion
Expand Down
44 changes: 44 additions & 0 deletions Src/ILGPU/ICache.cs
@@ -0,0 +1,44 @@
// -----------------------------------------------------------------------------
// ILGPU
// Copyright (c) 2016-2019 Marcel Koester
// www.ilgpu.net
//
// File: ICache.cs
//
// This file is part of ILGPU and is distributed under the University of
// Illinois Open Source License. See LICENSE.txt for details
// -----------------------------------------------------------------------------

namespace ILGPU
{
/// <summary>
/// Specifies which resources should be removed from the cache.
/// </summary>
public enum ClearCacheMode : int
{
/// <summary>
/// Removes all non-ILGPU objects form the caches.
/// </summary>
Default = 0,

/// <summary>
/// Removes everything from the caches.
/// </summary>
Everything = 1,
}

/// <summary>
/// Represents an object that contains internal caches.
/// </summary>
public interface ICache
{
/// <summary>
/// Clears all internal caches.
/// </summary>
/// <param name="mode">The clear mode.</param>
/// <remarks>
/// Implementations of this method are not guaranteed to be thread-safe.
/// </remarks>
void ClearCache(ClearCacheMode mode);
}
}
13 changes: 10 additions & 3 deletions Src/ILGPU/IR/IRContext.cs
Expand Up @@ -30,7 +30,7 @@ namespace ILGPU.IR
/// <summary>
/// Represents an IR context.
/// </summary>
public sealed partial class IRContext : DisposeBase
public sealed partial class IRContext : DisposeBase, ICache
{
#region Nested Types

Expand Down Expand Up @@ -554,9 +554,16 @@ public void GC()
}

/// <summary>
/// Clears this context and removes all nodes
/// Clears cached IR nodes.
/// </summary>
public void Clear()
[Obsolete("Use ClearCache(ClearCacheMode.Everything) instead")]
public void Clear() => ClearCache(ClearCacheMode.Everything);

/// <summary>
/// Clears cached IR nodes.
/// </summary>
/// <param name="mode">The clear mode.</param>
public void ClearCache(ClearCacheMode mode)
{
irLock.EnterWriteLock();
try
Expand Down
2 changes: 1 addition & 1 deletion Src/ILGPU/IR/Transformations/Inliner.cs
Expand Up @@ -53,7 +53,7 @@ public sealed class Inliner : OrderedTransformation

if ((source.MethodImplementationFlags & MethodImplAttributes.AggressiveInlining)
== MethodImplAttributes.AggressiveInlining ||
source.Module.Name == Context.AssemblyModuleName)
source.Module.Name == Context.FullAssemblyModuleName)
method.AddFlags(MethodFlags.Inline);
}

Expand Down
43 changes: 42 additions & 1 deletion Src/ILGPU/IR/Types/IRTypeContext.cs
Expand Up @@ -253,7 +253,7 @@ public TypeNode CreateType(Type type, MemoryAddressSpace addressSpace)
}

/// <summary>
/// Specializes the address space of the given <see cref="AddressSpaceType"/>.
/// Specializes the address space of the given <seeVoidType cref="AddressSpaceType"/>.
/// </summary>
/// <param name="addressSpaceType">The source type.</param>
/// <param name="addressSpace">The new address space.</param>
Expand Down Expand Up @@ -334,6 +334,47 @@ private T CreateType<T>(T type)
}
}

/// <summary>
/// Clears all internal caches.
/// </summary>
/// <param name="mode">The clear mode.</param>
public override void ClearCache(ClearCacheMode mode)
{
base.ClearCache(mode);

typeLock.EnterWriteLock();
try
{
unifiedTypes.Clear();

unifiedTypes.Add(VoidType, VoidType);
unifiedTypes.Add(StringType, StringType);

foreach (var basicType in BasicValueTypes)
{
var type = GetPrimitiveType(basicType);
unifiedTypes.Add(type, type);
}

unifiedTypes.Add(IndexType, IndexType);
}
finally
{
typeLock.ExitWriteLock();
}
}

#endregion

#region IDisposable

/// <summary cref="DisposeBase.Dispose(bool)"/>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
typeLock.Dispose();
}

#endregion
}
}

0 comments on commit cf83683

Please sign in to comment.