Ejemplo n.º 1
0
        /// <summary>
        ///     Creates a program from the provided source codes. The program is created, compiled, and linked.
        /// </summary>
        /// <param name="sources">The source codes from which the program is to be created.</param>
        /// <exception cref="OpenClException">
        ///     If the program could not be created, compiled, or linked, then an
        ///     <see cref="OpenClException" /> is thrown.
        /// </exception>
        /// <returns>Returns the created program.</returns>
        public Program CreateAndBuildProgramFromString(IEnumerable <string> sources)
        {
            // Loads the program from the specified source string
            IntPtr[] sourceList     = sources.Select(source => Marshal.StringToHGlobalAnsi(source)).ToArray();
            uint[]   sourceLengths  = sources.Select(source => (uint)source.Length).ToArray();
            IntPtr   programPointer =
                ProgramsNativeApi.CreateProgramWithSource(Handle, 1, sourceList, sourceLengths, out Result result);

            // Checks if the program creation was successful, if not, then an exception is thrown
            if (result != Result.Success)
            {
                throw new OpenClException("The program could not be created.", result);
            }

            // Builds (compiles and links) the program and checks if it was successful, if not, then an exception is thrown
            result = ProgramsNativeApi.BuildProgram(programPointer, 0, null, null, IntPtr.Zero, IntPtr.Zero);
            if (result != Result.Success)
            {
                // Cycles over all devices and retrieves the build log for each one, so that the errors that occurred can be added to the exception message (if any error occur during the retrieval, the exception is thrown without the log)
                Dictionary <string, string> buildLogs = new Dictionary <string, string>();
                foreach (Device device in Devices)
                {
                    try
                    {
                        string buildLog =
                            GetProgramBuildInformation <string>(programPointer, device, ProgramBuildInformation.Log)
                            .Trim();
                        if (!string.IsNullOrWhiteSpace(buildLog))
                        {
                            buildLogs.Add(device.Name, buildLog);
                        }
                    }
                    catch (OpenClException)
                    {
                    }
                }

                // Compiles the build logs into a formatted string and integrates it into the exception message
                string buildLogString = string.Join(
                    $"{Environment.NewLine}{Environment.NewLine}",
                    buildLogs.Select(
                        keyValuePair =>
                        $" Build log for device \"{keyValuePair.Key}\":{Environment.NewLine}{keyValuePair.Value}"
                        )
                    );
                throw new OpenClException(
                          $"The program could not be compiled and linked.{Environment.NewLine}{Environment.NewLine}{buildLogString}",
                          result
                          );
            }

            // Creates the new program and returns it
            return(new Program(programPointer));
        }
Ejemplo n.º 2
0
        private void InitCL(String[] kernelSource, String[] kernelNames, string compileArguments)
        {
            lock (lockObj)
            {
                if (!hasClInitialized && clDevice != null)
                {
                    Result err;
                    var    devicesArray = new IntPtr[] { clDevice };
                    clContext = ContextsNativeApi.CreateContext(IntPtr.Zero, 1, devicesArray, IntPtr.Zero, IntPtr.Zero, out err);
                    if (err != Result.Success)
                    {
                        throw new OpenClException("Failed to create context!", err);
                    }

                    commandQueue = CommandQueuesNativeApi.CreateCommandQueue(clContext, clDevice, CommandQueueProperty.None, out err);
                    if (err != Result.Success)
                    {
                        throw new OpenClException("Failed to create command queue!", err);
                    }

                    IntPtr[] sourceList = kernelSource.Select(source => Marshal.StringToHGlobalAnsi(source)).ToArray();
                    clProgram = ProgramsNativeApi.CreateProgramWithSource(clContext, 1, sourceList, null, out err);
                    if (err != Result.Success)
                    {
                        throw new OpenClException("Failed to create program!", err);
                    }

                    err = ProgramsNativeApi.BuildProgram(clProgram, 1, new IntPtr[] { clDevice }, compileArguments, IntPtr.Zero, IntPtr.Zero);
                    if (err != Result.Success)
                    {
                        var infoBuffer = GetProgramBuildInformation <string>(clProgram, clDevice, ProgramBuildInformation.Log);
                        if (err != Result.Success)
                        {
                            throw new OpenClException("Failed to build program! " + (infoBuffer == null ? "?" : infoBuffer.ToString()), err);
                        }
                    }

                    foreach (var item in kernelNames)
                    {
                        kernels[item] = KernelsNativeApi.CreateKernel(clProgram, item, out err);
                        if (err != Result.Success)
                        {
                            throw new OpenClException("Failed to create kernel: " + item, err);
                        }
                    }

                    hasClInitialized = true;
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a program from the provided source codes asynchronously. The program is created, compiled, and linked.
        /// </summary>
        /// <param name="sources">The source codes from which the program is to be created.</param>
        /// <exception cref="OpenClException">If the program could not be created, compiled, or linked, then an <see cref="OpenClException"/> is thrown.</exception>
        /// <returns>Returns the created program.</returns>
        public Task <Program> CreateAndBuildProgramFromStringAsync(IEnumerable <string> sources)
        {
            // Creates a new task completion source, which is used to signal when the build has completed
            TaskCompletionSource <Program> taskCompletionSource = new TaskCompletionSource <Program>();

            // Loads the program from the specified source string
            IntPtr[] sourceList     = sources.Select(source => Marshal.StringToHGlobalAnsi(source)).ToArray();
            uint[]   sourceLengths  = sources.Select(source => (uint)source.Length).ToArray();
            IntPtr   programPointer =
                ProgramsNativeApi.CreateProgramWithSource(Handle, 1, sourceList, sourceLengths, out Result result);

            // Checks if the program creation was successful, if not, then an exception is thrown
            if (result != Result.Success)
            {
                throw new OpenClException("The program could not be created.", result);
            }

            // Builds (compiles and links) the program and checks if it was successful, if not, then an exception is thrown
            Result result1 = result;

            result = ProgramsNativeApi.BuildProgram(programPointer, 0, null, null,
                                                    Marshal.GetFunctionPointerForDelegate(new BuildProgramCallback((builtProgramPointer, userData) =>
            {
                // Tries to validate the build, if not successful, then an exception is thrown
                try
                {
                    // Cycles over all devices and retrieves the build log for each one, so that the errors that occurred can be added to the exception message (if any error occur during the retrieval, the exception is thrown without the log)
                    Dictionary <string, string> buildLogs = new Dictionary <string, string>();
                    foreach (Device device in Devices)
                    {
                        try
                        {
                            string buildLog = GetProgramBuildInformation <string>(builtProgramPointer, device,
                                                                                  ProgramBuildInformation.Log).Trim();
                            if (!string.IsNullOrWhiteSpace(buildLog))
                            {
                                buildLogs.Add(device.Name, buildLog);
                            }
                        }
                        catch (OpenClException)
                        {
                        }
                    }

                    // Checks if there were any errors, if so then the build logs are compiled into a formatted string and integrates it into the exception message
                    if (buildLogs.Any())
                    {
                        string buildLogString = string.Join($"{Environment.NewLine}{Environment.NewLine}",
                                                            buildLogs.Select(keyValuePair =>
                                                                             $" Build log for device \"{keyValuePair.Key}\":{Environment.NewLine}{keyValuePair.Value}"));
                        taskCompletionSource.TrySetException(new OpenClException(
                                                                 $"The program could not be compiled and linked.{Environment.NewLine}{Environment.NewLine}{buildLogString}",
                                                                 result1));
                    }

                    // Since the build was successful, the program is created and the task completion source is resolved with it Creates the new program and returns it
                    taskCompletionSource.TrySetResult(new Program(builtProgramPointer));
                }
                catch (Exception exception)
                {
                    taskCompletionSource.TrySetException(exception);
                }
            })), IntPtr.Zero);

            // Checks if the build could be started successfully, if not, then an exception is thrown
            if (result != Result.Success)
            {
                if (result != Result.Success)
                {
                    taskCompletionSource.TrySetException(
                        new OpenClException("The program could not be compiled and linked.", result));
                }
            }

            // Returns the task which is resolved when the program was build successful or not
            return(taskCompletionSource.Task);
        }