/// <summary> /// Try to add appropriate attributes into the <see cref="BindingContext"/>, related to the shared memory region that holds the object. /// These attributes are used during the binding process to read/write from shared memory. /// </summary> private async Task <bool> TryPrepareAttributesAndBindCacheAwareAsync(BindingContext context, FileAccess access) { if (access == FileAccess.Write) { if (context.Value is SharedMemoryObject sharedMemoryObj) { // First copy the attributes and then add a specific attribute (mapName) for the particular invocation. var currentAttributes = Attributes.ToList(); SharedMemoryAttribute sharedMemoryAttribute = new SharedMemoryAttribute(sharedMemoryObj.MemoryMapName, sharedMemoryObj.Count); currentAttributes.Add(sharedMemoryAttribute); context.Attributes = currentAttributes.ToArray(); } else { // When binding in a cache aware manner, the write object must already be in shared memory return(false); } } await BindCacheAwareAsync(context, access); return(true); }
/// <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)); } } }