Build program

Help
2010-07-03
2012-12-21
  • Douglas Andrade

    Douglas Andrade - 2010-07-03

    Hello;

    I have the following problem with Cloo: I'm using OpenCL with the CPU, one Radeon 5770 GPU and one 4890 GPU. I sometimes create programs that are supposed to compile only in the 5770 and I know they won't compile on the 4890. In those cases I need to explicitly create a list containing only the 5770 GPU before compiling.

    I would like to suggest that Cloo tries to compile the code using all the available devices and only return an exception if the code doesn't compile in any of them.

    Cloo could return some parameter to tell which were the devices that actually were able to compile the code.

    Thanks

     
  • nythrix

    nythrix - 2010-07-07

    I will add this functionality.

    Thanks for the tip.

     
  • nythrix

    nythrix - 2010-07-20

    This is basically all what it takes:

                ICollection<ComputeDevice> result = new Collection<ComputeDevice>();
                try { Build(null, options, null, IntPtr.Zero); }
                catch (ComputeException ex)
                {
                    // Catch certain exception(s)
                }
                
                foreach (ComputeDevice device in Devices)
                    if (GetBuildStatus(device) == ComputeProgramBuildStatus.Success)
                        result.Add(device);
                return result;
    

    I have a problem with it though. Looking at the list of error codes in clBuildProgram I cannot determine, which of the matching exceptions are acceptable and should be catched and which ones should be left propagating because they're not device related. Even worse, not every device build failure happens because of the device's disability to build a certain piece of code (or link binary). This would trigger false positives.
    Given that the build process is the most erroneous part of an application working with OpenCL, I really dislike the idea of a silent Build() method. Therefore a catch-all strategy is out of question.

    How about something from the other end? A ComputeContext.GetDeviceByName() method might help a bit:

    program.Build(new ComputeDevice[]{program.Context.GetDeviceByName("5770")}, null, null, IntPtr.Zero);
    

    It won't help with building the array/list you mention but at least you won't have to walk through all sorts of device lists to find the device you need.

    I'm open to other suggestions, too.

     
  • Douglas Andrade

    Douglas Andrade - 2010-07-20

    This is sort of what I have been doing up to now, but what I'm suggesting is actually simpler than that. Let Cloo throw the exceptions just as it normally would; just don't prevent it from compiling on devices it would compile. Consider this situation:

    Suppose I have 3 devices: a CPU and 2 GPUs, one Radeon 4890 and one Radeon 5770 and my context has all three devices. I have a piece of code that won't compile on 4890.

    How it is now:

    prog.Build will compile code for CPU and will throw an Exception when compiling for the 4890 thus not even trying the 5770. Exception X is thrown.

    How I suggest it to be:

    prog.Build will compile for the CPU and encounter an exception for 4890. Instead of throwing the exception right away, it tries to compile for 5770 and throws exception X only in the end, perhaps returning a collection of Devices in which Build was OK.

    You see, this is not necessary, just convenient, the same Exception would be thrown, but in the end, and returning the subset of Devices that could build the program.

    And again congratulations for the great work.

     
  • nythrix

    nythrix - 2010-07-21

    just don't prevent it from compiling on devices it would compile.

    Problem is that's how clBuildProgram works. Cloo tries not to get in the way of OpenCL functions wherever possible.

    I ended up with this method in ComputeProgram:

    public ICollection<ComputeDevice> Build(string options, ICollection<ComputeException> exceptions)
    {
        ICollection<ComputeDevice> result = new Collection<ComputeDevice>();
        foreach (ComputeDevice device in Devices)
        {
            try { Build(new ComputeDevice[]{device}, options, null, IntPtr.Zero); }
            catch (ComputeException ex) 
            {
                if (exceptions != null && !exceptions.IsReadOnly) 
                    exceptions.Add(ex);
                continue; 
            }
            if (GetBuildStatus(device) == ComputeProgramBuildStatus.Success)
                result.Add(device);
        }
        return (result.Count > 0) ? result : null;
    }
    

    This should work the way you prefer. However, walking through exceptions and figuring out what happened is a bit obscure.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks