internal static void GenerateScanReduce <T, TScanReduce>( CLBackend backend, CLCodeGenerator codeGenerator, Value value, string scanReduceOperation) where T : struct where TScanReduce : struct, IScanReduceOperation <T> { // Allocate target and load source argument var reduce = value as MethodCall; var sourceValue = codeGenerator.Load(reduce[0]); var target = codeGenerator.Allocate(value); // Resolve OpenCL command TScanReduce scanReduce = default; var clCommand = scanReduce.CLCommand; if (string.IsNullOrWhiteSpace(clCommand)) { throw new InvalidCodeGenerationException(); } using var statement = codeGenerator.BeginStatement(target); statement.AppendCommand(scanReduceOperation + clCommand); statement.BeginArguments(); statement.AppendCast(typeof(T).GetArithmeticBasicValueType()); statement.Append(sourceValue); statement.EndArguments(); }
/// <summary> /// Generates intrinsic math instructions for the following kinds: /// Rcp /// </summary> /// <param name="backend">The current backend.</param> /// <param name="codeGenerator">The code generator.</param> /// <param name="value">The value to generate code for.</param> public static void GenerateMathIntrinsic( CLBackend backend, CLCodeGenerator codeGenerator, Value value) { // Manually generate code for "1.0 / argument" var arithmeticValue = value as UnaryArithmeticValue; var argument = codeGenerator.Load(arithmeticValue.Value); var target = codeGenerator.Allocate(arithmeticValue); var operation = CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Div, arithmeticValue.BasicValueType.IsFloat(), out var isFunction); using var statement = codeGenerator.BeginStatement(target); statement.AppendCast(arithmeticValue.ArithmeticBasicValueType); if (isFunction) { statement.AppendCommand(operation); statement.BeginArguments(); } else { statement.OpenParen(); } statement.AppendCast(arithmeticValue.ArithmeticBasicValueType); if (arithmeticValue.BasicValueType == BasicValueType.Float32) { statement.AppendConstant(1.0f); } else { statement.AppendConstant(1.0); } if (!isFunction) { statement.AppendCommand(operation); } statement.AppendArgument(); statement.AppendCast(arithmeticValue.ArithmeticBasicValueType); statement.Append(argument); if (isFunction) { statement.EndArguments(); } else { statement.CloseParen(); } }
/// <summary> /// The OpenCL implementation. /// </summary> /// <remarks> /// Note that this function signature corresponds to the OpenCL-backend specific /// delegate type <see cref="CLIntrinsic.Handler"/>. /// </remarks> static void GenerateCLCode( CLBackend backend, CLCodeGenerator codeGenerator, Value value) { // The passed value will be the call node in this case // Load X parameter variable (first argument) var xVariable = codeGenerator.Load(value[0]); // Allocate target variable to write our result to var target = codeGenerator.Allocate(value); // Emit our desired instructions using var statement = codeGenerator.BeginStatement(target); statement.Append(xVariable); statement.AppendCommand( CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Mul, false, out var _)); statement.AppendConstant(2); }