/// <summary> /// Gets or creates the given type in OpenCL. /// </summary> /// <param name="typeNode">The type to declare.</param> /// <returns>The declared type name.</returns> private string GetOrCreateType(TypeNode typeNode) { Debug.Assert(!(typeNode is ViewType), "Invalid view type"); if (mapping.TryGetValue(typeNode, out string clName)) { return(clName); } if (typeNode is PointerType pointerType) { // Make sure the element type is known GetOrCreateType(pointerType.ElementType); clName = GetTypeName(typeNode); } else if (typeNode is StructureType structureType) { // Make sure all field types are known foreach (var fieldType in structureType.Fields) { GetOrCreateType(fieldType); } clName = CLInstructions.StructTypePrefix + " " + GetTypeName(typeNode); } else if (typeNode is PaddingType paddingType) { clName = GetOrCreateType(paddingType.PrimitiveType); } else if (typeNode is PrimitiveType primitiveType16 && primitiveType16.BasicValueType == BasicValueType.Float16 && !Capabilities.Float16) { throw CLCapabilityContext.GetNotSupportedFloat16Exception(); }
/// <summary> /// Constructs a new OpenCL accelerator reference. /// </summary> /// <param name="platformId">The OpenCL platform id.</param> /// <param name="deviceId">The OpenCL device id.</param> public CLDevice(IntPtr platformId, IntPtr deviceId) { if (platformId == IntPtr.Zero) { throw new ArgumentOutOfRangeException(nameof(platformId)); } if (deviceId == IntPtr.Zero) { throw new ArgumentOutOfRangeException(nameof(deviceId)); } Backends.Backend.EnsureRunningOnNativePlatform(); PlatformId = platformId; DeviceId = deviceId; InitPlatformInfo(); InitDeviceInfo(); InitGridInfo(); InitVendorAndWarpSizeInfo(); InitMemoryInfo(); InitCInfo(); InitExtensions(); // Resolve extension method getKernelSubGroupInfo = CurrentAPI.GetExtension <clGetKernelSubGroupInfoKHR>( platformId); // Init capabilities Capabilities = new CLCapabilityContext(this); InitGenericAddressSpaceSupport(); }
/// <summary> /// Constructs a new type generator and defines all required types /// in OpenCL during construction. /// </summary> /// <param name="typeContext">The associated type context.</param> /// <param name="capabilities">The supported capabilities.</param> internal CLTypeGenerator( IRTypeContext typeContext, CLCapabilityContext capabilities) { TypeContext = typeContext; Capabilities = capabilities; // Declare primitive types mapping[typeContext.VoidType] = "void"; mapping[typeContext.StringType] = "__constant char*"; foreach (var basicValueType in IRTypeContext.BasicValueTypes) { if (basicValueType == BasicValueType.Float64 && TypeContext.MathMode == MathMode.Fast32BitOnly) { continue; } else if (basicValueType == BasicValueType.Float16 && !capabilities.Float16) { continue; } else if (basicValueType == BasicValueType.Float64 && !capabilities.Float64) { continue; } var primitiveType = typeContext.GetPrimitiveType(basicValueType); mapping[primitiveType] = GetBasicValueType(basicValueType); } }
private void ThrowIfUnsupportedAtomicOperation(AtomicValue atomic) { if ((atomic.ArithmeticBasicValueType == ArithmeticBasicValueType.Int64 || atomic.ArithmeticBasicValueType == ArithmeticBasicValueType.UInt64 || atomic.ArithmeticBasicValueType == ArithmeticBasicValueType.Float64) && !TypeGenerator.Capabilities.Int64_Atomics) { throw CLCapabilityContext.GetNotSupportedInt64_AtomicsException(); } }
/// <summary> /// Constructs a new OpenCL accelerator. /// </summary> /// <param name="context">The ILGPU context.</param> /// <param name="description">The accelerator description.</param> internal CLAccelerator(Context context, CLDevice description) : base(context, description) { Backends.Backend.EnsureRunningOnNativePlatform(); if (!description.Capabilities.GenericAddressSpace) { throw CLCapabilityContext.GetNotSupportedGenericAddressSpaceException(); } // Create new context CLException.ThrowIfFailed( CurrentAPI.CreateContext(DeviceId, out var contextPtr)); NativePtr = contextPtr; Bind(); DefaultStream = CreateStreamInternal(); InitVendorFeatures(); InitSubGroupSupport(description); Init(new CLBackend(Context, Capabilities, Vendor, CLStdVersion)); }
/// <summary> /// Constructs a new OpenCL source backend. /// </summary> /// <param name="context">The context to use.</param> /// <param name="capabilities">The supported capabilities.</param> /// <param name="vendor">The associated major vendor.</param> /// <param name="clStdVersion">The OpenCL C version passed to -cl-std.</param> public CLBackend( Context context, CLCapabilityContext capabilities, CLDeviceVendor vendor, CLCVersion clStdVersion) : base( context, capabilities, BackendType.OpenCL, new CLArgumentMapper(context)) { Vendor = vendor; CLStdVersion = clStdVersion; InitIntrinsicProvider(); InitializeKernelTransformers(builder => { var transformerBuilder = Transformer.CreateBuilder( TransformerConfiguration.Empty); transformerBuilder.AddBackendOptimizations <CodePlacement.GroupOperands>( new CLAcceleratorSpecializer( PointerType, Context.Properties.EnableIOOperations), context.Properties.InliningMode, context.Properties.OptimizationLevel); builder.Add(transformerBuilder.ToTransformer()); }); // Build a list of extensions to enable for each OpenCL kernel. var extensionBuilder = new StringBuilder(); foreach (var extensionName in Capabilities.Extensions) { extensionBuilder.Append("#pragma OPENCL EXTENSION "); extensionBuilder.Append(extensionName); extensionBuilder.AppendLine(" : enable"); } extensions = extensionBuilder.ToString(); }
/// <summary> /// Constructs a new OpenCL source backend. /// </summary> /// <param name="context">The context to use.</param> /// <param name="capabilities">The supported capabilities.</param> /// <param name="vendor">The associated major vendor.</param> public CLBackend( Context context, CLCapabilityContext capabilities, CLAcceleratorVendor vendor) : base( context, capabilities, BackendType.OpenCL, BackendFlags.None, new CLArgumentMapper(context)) { Vendor = vendor; InitIntrinsicProvider(); InitializeKernelTransformers( IntrinsicSpecializerFlags.None, builder => { var transformerBuilder = Transformer.CreateBuilder( TransformerConfiguration.Empty); transformerBuilder.AddBackendOptimizations( new CLAcceleratorSpecializer(PointerType), context.Flags, context.OptimizationLevel); builder.Add(transformerBuilder.ToTransformer()); }); // Build a list of extensions to enable for each OpenCL kernel. var extensionBuilder = new StringBuilder(); foreach (var extensionName in Capabilities.Extensions) { extensionBuilder.Append("#pragma OPENCL EXTENSION "); extensionBuilder.Append(extensionName); extensionBuilder.AppendLine(" : enable"); } extensions = extensionBuilder.ToString(); }
/// <summary> /// Resolves the given basic-value type to an atomic OpenCL type name. /// </summary> /// <param name="basicValueType">The basic-value type to resolve.</param> /// <returns>The resolved atomic OpenCL type name.</returns> public string GetAtomicType(ArithmeticBasicValueType basicValueType) => basicValueType == ArithmeticBasicValueType.Float16 && !Capabilities.Float16 ? throw CLCapabilityContext.GetNotSupportedFloat16Exception() : basicValueType == ArithmeticBasicValueType.Float64 && !Capabilities.Float64 ? throw CLCapabilityContext.GetNotSupportedFloat64Exception() : AtomicTypeMapping[(int)basicValueType];
/// <summary> /// Resolves the given basic-value type to an OpenCL type name. /// </summary> /// <param name="basicValueType">The basic-value type to resolve.</param> /// <returns>The resolved OpenCL type name.</returns> public string GetBasicValueType(BasicValueType basicValueType) => basicValueType == BasicValueType.Float16 && !Capabilities.Float16 ? throw CLCapabilityContext.GetNotSupportedFloat16Exception() : BasicTypeMapping[(int)basicValueType];