2 Replies Latest reply on Jan 8, 2013 5:21 AM by Meteorhead

    clEnqueueMigrateMemObjects vs cl::CommandQueue::enqueueMigrateMemObjects




      I have been tweaking the code I recently attached in another topic, and have come cross a problem where the C API works perfectly fine, whereas the C++ wrapper always fails. The error code is -38 which corresponds to CL_INVALID_COMMAND_QUEUE, and the spec says:

      CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command_queue.


      Now, I know for sure that the command_queue is alright, otherwise everything else would fail afterwards. Since there is a finish on the queue right after the command is issued, no such problem can occur, where something gets deleted on the stack while the operation is still in progress. Everything that is in memory stays there until the operation finishes. If I obtain all the C handlers from the warpper objects, and call the old C API, everything works fine, but the wrapper function corresponding to the same functionality fails. I checked cl.hpp to see what it does differently, but I could not find my mistake. It seems to do the correct stuff, so the problem must be on my side. What am I doing wrong?


          std::vector<cl::Buffer> input1_buffs(devices.size()), input2_buffs(devices.size()), output_buffs(devices.size());
          for(unsigned int i = 0 ; i < devices.size() ; ++i)
              cl_buffer_region region;
              region.origin = i*batch_size;
              region.size = batch_size;
                  input1_buffs.at(i) = input1_buffer.createSubBuffer(CL_MEM_READ_ONLY, CL_BUFFER_CREATE_TYPE_REGION, &region);
                  input2_buffs.at(i) = input2_buffer.createSubBuffer(CL_MEM_READ_ONLY, CL_BUFFER_CREATE_TYPE_REGION, &region);
                  output_buffs.at(i) = output_buffer.createSubBuffer(CL_MEM_WRITE_ONLY,CL_BUFFER_CREATE_TYPE_REGION, &region);
                  // A little C API (dunno why the wrapper does not work)
                  cl_mem send[3] = {input1_buffs.at(i)(), input2_buffs.at(i)(), output_buffs.at(i)()};
                  cl_int error = CL_SUCCESS;
                  clEnqueueMigrateMemObjects(queues.at(i)(), 3, send, NULL, 0, NULL, NULL);
                  if(error != CL_SUCCESS) {std::cerr << "clEnqueueMigrateMemObjects(" << error << ")" << std::endl; return EXIT_FAILURE;}
                  // C++ wrapper that does not seem to work
                  std::vector<cl::Memory> send(3);
                  queues.at(i).enqueueMigrateMemObjects(send, NULL, NULL, NULL);
              catch(cl::Error err) {std::cerr << err.what() << "(" << err.err() << ")" << std::endl; return EXIT_FAILURE;}


      A little help would be apreciated. (Naturally not both parts of the code are present at the same time)

        • Re: clEnqueueMigrateMemObjects vs cl::CommandQueue::enqueueMigrateMemObjects
          1.             std::vector<cl::Memory> send(3); 
          2.             send.push_back(input1_buffs.at(i)); 
          3.             send.push_back(input2_buffs.at(i)); 
          4.             send.push_back(output_buffs.at(i)); 


          You constructed a vector of size three and then pushed more into it. You now have a vector of size 6 with three default-constructed cl::Memory objects on the front.


          It should work if you drop the 3, I think.

            • Re: clEnqueueMigrateMemObjects vs cl::CommandQueue::enqueueMigrateMemObjects

              Hi Lee,


              first of all thank you for your suggestion, it was useful, however there were more problems with my program which got solved in the topic




              (The problems originated from using default constructed contexts when creating buffers, and there might have been other defaults involved. I revised my code and got really pedantic about specifying everything. Then it worked)


              I would like to make some remarks, suggestions and ask some questions about the C++ wrapper (assuming you are affiliated with it's development), but as there are many ideas and they are not closely related to this topic, and other might have ideas too, let me open a new topic for it.