void CtEvent::getEventList(EventList& event_list) { DEB_MEMBER_FUNCT(); AutoMutex l = lock(); DEB_PARAM() << DEB_VAR2(event_list.size(), m_event_list.size()); if (!event_list.empty()) THROW_CTL_ERROR(InvalidValue) << "Not empty event_list (" << DEB_VAR1(event_list.size()) << "): " << "Where all the events deleted?"; else if (hasRegisteredCallback()) DEB_WARNING() << "An EventCallback is registered, events are dispatched"; event_list = m_event_list; m_event_list.clear(); }
void EventList::append(const EventList& other) { for(size_t i = 0; i < other.size(); ++i) { cl_event e = other._events[i]; clRetainEvent(e); _events.push_back(e); } }
/** * \brief ocl::Image::copyToAsync Copies asynchronously from this Image to the destination Image. * * \param src_origin is the 3D offset in bytes from which the Image is read. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. * \param dest is the Image into which the data is going to be copied. * \param dest_origin is the 3D offset in bytes from which the destionation Image is read. * \param list contains all events for which this command has to wait. * \return event which can be integrated into other EventList. */ ocl::Event ocl::Image::copyToAsync(size_t *src_origin, const size_t *region, const Image &dest, size_t *dest_origin, const EventList &list) { TRUE_ASSERT(this->context() == dest.context(), "Context of this and dest must be equal"); TRUE_ASSERT(this->id() != dest.id(), "Images must not be equal this->id() " << this->id() << "; other.id " << dest.id()); cl_event event_id; OPENCL_SAFE_CALL( clEnqueueCopyImage(this->activeQueue().id(), this->id(), dest.id(), src_origin, dest_origin, region, list.size(), list.events().data(), &event_id) ); return ocl::Event(event_id, this->context()); }
/** * \brief ocl::Image::copyToAsync Copies asynchronously from this Image to the destination Image. * * \param queue is a command queue on which the command is executed. * \param src_origin is the 3D offset in bytes from which the Image is read. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. * \param dest is the Image into which the data is going to be copied. * \param dest_origin is the 3D offset in bytes from which the destionation Image is read. * \param list contains all events for which this command has to wait. * \return event which can be integrated into other EventList. */ ocl::Event ocl::Image::copyToAsync(const Queue &queue, size_t *src_origin, const size_t *region, const Image &dest, size_t *dest_origin, const EventList &list) { TRUE_ASSERT(this->context() == dest.context(), "Context of this and dest must be equal"); TRUE_ASSERT(queue.context() == *this->context(), "Context of queue and this must be equal"); cl_event event_id; OPENCL_SAFE_CALL( clEnqueueCopyImage(queue.id(), this->id(), dest.id(), src_origin, dest_origin, region, list.size(), list.events().data(), &event_id) ); return ocl::Event(event_id, this->context()); }
// In specific order many at a time: bool waitForEventList(const EventList& evts, Duration timeout=Duration::seconds(5)) { for(uint idx = 0; idx < evts.size(); idx++) { Event read_evt; bool got_event = _events.blockingPop(read_evt, timeout); TS_ASSERT(got_event); if (!got_event) return false; TS_ASSERT_EQUALS(evts[idx], read_evt); if (evts[idx] != read_evt) return false; } return true; }
/** * \brief ocl::Image::map Maps the Image into the host memory. * * No data transfer is performed. Note that in order to map data of the Image the active queue must be a cpu and must have been allocated * with the Image access mode AllocHost. You cannot modify the Image with OpenCL until unmap. * \param ptr is returned and contains the address of a pointer to the host memory. * \param origin is the 3D offset in bytes from which the image is read. * \param region is the 3D region in bytes to be mapped. * \param access specifies in what way the host_mem is used. * \param list contains all events for which this command has to wait. * \return event which can be integrated into other EventList */ ocl::Event ocl::Image::mapAsync(void **ptr, size_t *origin, const size_t *region, Memory::Access access, const EventList &list) const { TRUE_ASSERT(this->activeQueue().device().isCpu(), "Device " << this->activeQueue().device().name() << " is not a cpu!"); cl_int status; cl_event event_id; cl_map_flags flags = access; *ptr = clEnqueueMapImage(this->activeQueue().id(), this->id(), CL_TRUE, flags, origin, region, 0, 0, list.size(), list.events().data(), &event_id, &status); OPENCL_SAFE_CALL (status ) ; TRUE_ASSERT(ptr != NULL, "Could not map image!"); return ocl::Event(event_id, this->context()); }
std::vector<double> beatTrack(const AgentParameters ¶ms, const EventList &events, const EventList &beats) { AgentList agents; int count = 0; double beatTime = -1; if (!beats.empty()) { count = beats.size() - 1; EventList::const_iterator itr = beats.end(); --itr; beatTime = itr->time; } if (count > 0) { // tempo given by mean of initial beats double ioi = (beatTime - beats.begin()->time) / count; agents.push_back(new Agent(params, ioi)); } else // tempo not given; use tempo induction agents = Induction::beatInduction(params, events); if (!beats.empty()) { for (AgentList::iterator itr = agents.begin(); itr != agents.end(); ++itr) { (*itr)->beatTime = beatTime; (*itr)->beatCount = count; (*itr)->events = beats; } } agents.beatTrack(events, params, -1); Agent *best = agents.bestAgent(); std::vector<double> resultBeatTimes; if (best) { best->fillBeats(beatTime); for (EventList::const_iterator itr = best->events.begin(); itr != best->events.end(); ++itr) { resultBeatTimes.push_back(itr->time); } } for (AgentList::iterator ai = agents.begin(); ai != agents.end(); ++ai) { delete *ai; } return resultBeatTimes; }
/* Merge all tracks into one big track. This will not copy any event * and only return a list of pointers to the events in the right order. * Note though that this will modify the relative_* times! * * The tracks will not be modified but may not be used later for * playback since the times are messed up (but you could reconstruct * them using the absolute_* times) * * The parameter muted is a set of muted track/channel combinations in * the format ttttcccc, that is the last 4 bits are the channel and the * remaining bits are the track: * (track_nr << 4) | channel_nr * */ EventList MidiFile::mergedTracks(std::set<int> muted) { EventList result; typedef std::vector<_track> trackv; trackv tracks; int tindex = 0; for (TrackList::iterator t = m_tracks.begin(); t != m_tracks.end(); ++t) { _track tentry; tentry.t = *t; tentry.pos = 0; tentry.size = (*t)->size(); tentry.index = tindex; tracks.push_back(tentry); ++tindex; } bool exhausted; MidiEvent* min_event; _track* min_track; int combination; std::map<int, int> chanmap; int nextchan = 0; for (;;) { exhausted = true; min_event = 0; min_track = 0; for (trackv::iterator t = tracks.begin(); t != tracks.end(); ++t) { if (t->pos < t->size) { exhausted = false; if (min_event == 0 || t->t->at(t->pos)->absolute_musec < min_event->absolute_musec) { min_event = t->t->at(t->pos); min_track = &(*t); } } } if (exhausted) break; ++min_track->pos; if (min_event->type() == Event_Note_On) { NoteOnEvent *e = dynamic_cast<NoteOnEvent*>(min_event); combination = min_track->index << 4 | e->getChannel(); e->muted = (muted.find(combination) != muted.end()); if (chanmap.find(combination) == chanmap.end()) { chanmap[combination] = nextchan; ++nextchan; } e->setChannel(chanmap[combination]); } else if (min_event->type() == Event_Note_Off) { NoteOffEvent *e = dynamic_cast<NoteOffEvent*>(min_event); combination = min_track->index << 4 | e->getChannel(); e->muted = (muted.find(combination) != muted.end()); if (chanmap.find(combination) == chanmap.end()) { chanmap[combination] = nextchan; ++nextchan; } e->setChannel(chanmap[combination]); } result.push_back(min_event); } int dticks; double dmusec; for (size_t i = 0; i < result.size(); ++i) { if (i == 0) { dticks = result[i]->absolute_ticks; dmusec = result[i]->absolute_musec; } else { dticks = result[i]->absolute_ticks - result[i-1]->absolute_ticks; dmusec = result[i]->absolute_musec - result[i-1]->absolute_musec; } result[i]->relative_ticks = dticks; result[i]->relative_musec = dmusec; } return result; }
int runFishhook(int argc, char** argv) { parseFishOptions(argc, argv); if (opt::verbose) { std::cerr << "FishHook Params: " << std::endl << "\tWidth: " << SeqLib::AddCommas(opt::width) << std::endl << "\tEvents: " << opt::events << std::endl << "\tCoverage Mask: " << opt::coverage << std::endl << "\tSlop: " << SeqLib::AddCommas(opt::slop) << std::endl << "\tInterval Tracks: " << std::endl; for (auto& i : opt::interval_files) std::cerr << "\t-- " << i << std::endl; std::cerr << "\tScored Tracks: " << std::endl; for (auto& i : opt::scored_files) std::cerr << "\t-- " << i << std::endl; std::cerr << "\tSequence Features: " << std::endl; for (auto& i : opt::seq_features) std::cerr << "\t-- " << i << std::endl; } // read in the covariate tracks SeqHashMap<std::string, Fractions> intervals; // read a header for info SeqLib::BamReader rdr; if (!rdr.Open(opt::bam)) { std::cerr << "Error: Could not read BAM supplied by -b: " << opt::bam << std::endl; exit(EXIT_FAILURE); } hdr = rdr.Header(); // read in the reference genome SeqLib::RefGenome ref; if (!ref.LoadIndex(opt::refgenome)) { if (opt::seq_features.size()) { std::cerr << "Error: Could not read referene genome supplied by -G: " << opt::refgenome << std::endl; exit(EXIT_FAILURE); } } // read in the events if (opt::verbose) std::cerr << "...reading events " << opt::events << std::endl; EventList events; if (!events.readFromBed(opt::events, hdr)) { std::cerr << "Error: Could not read events BED: " << opt::events << std::endl; exit(EXIT_FAILURE); } if (opt::verbose) std::cerr << "...read in " << SeqLib::AddCommas(events.size()) << " events" << std::endl; events.CreateTreeMap(); // create the tiled regions FishHookTiles fish(opt::width, opt::slop, hdr.GetHeaderSequenceVector()); if (opt::verbose) std::cerr << "...constructed " << SeqLib::AddCommas(fish.size()) << " fishhook intervals" << std::endl; fish.CreateTreeMap(); // read the coverage mask SeqLib::GRC cov; if (!opt::coverage.empty()) { if (opt::verbose) std::cerr << "...reading coverage mask " << opt::coverage << std::endl; cov.ReadBED(opt::coverage, hdr); if (opt::verbose) std::cerr << "...read in " << SeqLib::AddCommas(cov.size()) << " covered regions " << std::endl; if (!cov.size()) { std::cerr << "Non-empty coverage track read with 0 regions. Check that is non-empty BED" << std::endl; exit(EXIT_FAILURE); } if (opt::verbose) std::cerr << "...creating interval tree map on covered regions and overlapping with tiles" << std::endl; cov.CreateTreeMap(); // find covered amount per tile std::vector<int32_t> q, s; SeqLib::GRC ovlp; // fish is subject if (fish.size() > cov.size()) // do in most efficient order ovlp = cov.FindOverlaps(fish, q, s, false); else ovlp = fish.FindOverlaps(cov, s, q, false); if (opt::verbose) std::cerr << "..." << SeqLib::AddCommas(ovlp.size()) << " regions are covered" << std::endl; // set the amount covered by each for (size_t i = 0; i < ovlp.size(); ++i) { fish[s[i]].covered += (double)ovlp[i].Width() / fish[s[i]].Width(); } // mask the events q.clear(); s.clear(); ovlp.clear(); // events is subject if (events.size() > cov.size()) // do in most efficient order ovlp = cov.FindOverlaps(events, q, s, false); else ovlp = events.FindOverlaps(cov, s, q, false); EventList newe; // set the amount covered by each for (size_t i = 0; i < ovlp.size(); ++i) { newe.add(Event(ovlp[i], events.at(s[i]).id)); } events = newe; events.CreateTreeMap(); if (opt::verbose) std::cerr << "...kept " << SeqLib::AddCommas(events.size()) << " events after mask" << std::endl; } else { for (auto& i : fish) i.covered = 1; // the entire thing is covered if no mask provided } // read in the interval tracks for (auto& i : opt::interval_files) read_track(i, intervals, cov, false); for (auto& i : opt::scored_files) read_track(i, intervals, cov, true); // count events per tile (also de-dupes on patient per bin) fish.CountEvents(events); // overlap the covariates with the tiles for (auto& i : intervals) { fish.AddIntervalCovariate(i.first, i.second); } // make the matrix FishModel fm; fm.AddTiles(fish); fm.SetNumThreads(opt::num_threads); fm.EstimateOLS(); fm.CooksDistance(fm.GetOLS()); // write the covariates fish.PrintBEDHeader(std::cout); fish.PrintBED(std::cout, hdr); return 0; }
/*! \brief Releases access to this Image. * * Access is released to this Image. * \param q is the active OpenCL queue. * \returns whether releasing was successful or not. */ void ocl::Image::releaseAccess(Queue &q, const EventList& list) { cl_event event_id; OPENCL_SAFE_CALL( clEnqueueReleaseGLObjects(q.id(), 1, &this->_id, list.size(), list.events().data(), &event_id) ); }
/** * \brief ocl::Image::writeAsync Transfers data from host memory to this Image. * * Waits until the event list is completed. Be sure that the queue * and this Image are in the same context. * \param queue is a command queue on which the command is executed. * \param origin is the 3D offset in bytes from which the Image is read. * \param ptr_to_host_data must point to a memory location whith region bytes available. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. * \param list contains all events for which this command has to wait. * \return an event which can be further put into an event list for synchronization. */ ocl::Event ocl::Image::writeAsync(const Queue &queue, size_t *origin, const void *ptr_to_host_data, const size_t *region, const EventList &list) const { TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0"); TRUE_ASSERT(queue.context() == *this->context(), "Context of queue and this must be equal"); cl_event event_id; OPENCL_SAFE_CALL( clEnqueueWriteImage(queue.id(), this->id(), CL_FALSE, origin, region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), &event_id) ); return ocl::Event(event_id, this->context()); }
/** * \brief ocl::Image::write Transfers data from host memory to this Image. * * You can be sure that the data is read. Be sure that the queue * and this Image are in the same context. * \param queue is a command queue on which the command is executed. * \param ptr_to_host_data must point to a memory location whith region bytes available. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. */ void ocl::Image::write(const Queue& queue, const void *ptr_to_host_data, const size_t *region, const EventList &list) const { TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0"); TRUE_ASSERT(queue.context() == *this->context(), "Context of queue and this must be equal"); std::vector<size_t> origin = {0, 0, 0}; OPENCL_SAFE_CALL( clEnqueueWriteImage(queue.id(), this->id(), CL_TRUE, origin.data(), region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), NULL) ); OPENCL_SAFE_CALL( clFinish(queue.id()) ); }
/** * \brief ocl::Image::writeAsync Transfers data from host memory to this Image. * * Waits until the event list is completed. * \param origin is the 3D offset in bytes from which the Image is read. * \param ptr_to_host_data must point to a memory location whith region bytes available. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. * \param list contains all events for which this command has to wait. * \return an event which can be further put into an event list for synchronization. */ ocl::Event ocl::Image::writeAsync(size_t *origin, const void *ptr_to_host_data, const size_t *region, const EventList &list) const { TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0"); cl_event event_id; OPENCL_SAFE_CALL( clEnqueueWriteImage(this->activeQueue().id(), this->id(), CL_FALSE, origin, region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), &event_id) ); return ocl::Event(event_id, this->context()); }
/** * \brief ocl::Image::write Transfers data from host memory to this Image. * * You can be sure that the data is write. * \param ptr_to_host_data must point to a memory location whith region bytes available. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. */ void ocl::Image::write(const void *ptr_to_host_data, const size_t *region, const EventList &list) const { TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0"); std::vector<size_t> origin = {0, 0, 0}; OPENCL_SAFE_CALL( clEnqueueWriteImage(this->activeQueue().id(), this->id(), CL_TRUE, origin.data(), region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), NULL) ); OPENCL_SAFE_CALL( clFinish(this->activeQueue().id()) ); }
void dumpEvents( const EventList& events ) { for ( int i = 0; i < events.size(); ++i ) events[i].dump(); }
void EventsWindow::eventContextMenu(const QPoint &pos) { EventsView *view = qobject_cast<EventsView*>(sender()); if (!view) return; EventList selectedEvents = view->selectedEvents(); EventList selectedMediaEvents = selectedEvents.filter(MediaEventFilter()); EventList selectedCameraEvents = selectedEvents.filter(CameraEventFilter()); QMenu menu(view); QAction *aPlay = menu.addAction(tr("Play video")); aPlay->setEnabled(selectedMediaEvents.size() == 1); menu.setDefaultAction(aPlay); QAction *aPlayWindow = menu.addAction(tr("Play in a new window")); aPlayWindow->setEnabled(selectedMediaEvents.size() == 1); menu.addSeparator(); QAction *aSave = menu.addAction(tr("Save video")); aSave->setEnabled(!selectedMediaEvents.isEmpty()); menu.addSeparator(); QAction *aSelectOnly = menu.addAction(tr("Show only this camera")); aSelectOnly->setEnabled(!selectedCameraEvents.isEmpty()); QAction *aSelectElse = menu.addAction(tr("Exclude this camera")); aSelectElse->setEnabled(!selectedCameraEvents.isEmpty()); QAction *act = menu.exec(view->mapToGlobal(pos)); if (!act) return; else if (act == aPlay) showEvent(view->currentIndex()); else if (act == aPlayWindow) { ModelEventsCursor *modelEventsCursor = new ModelEventsCursor(); modelEventsCursor->setModel(view->model()); modelEventsCursor->setCameraFilter(selectedMediaEvents.at(0).locationCamera()); modelEventsCursor->setIndex(view->currentIndex().row()); EventViewWindow::open(selectedMediaEvents.at(0), modelEventsCursor); } else if (act == aSave) { if (selectedMediaEvents.size() == 1) bcApp->eventDownloadManager()->startEventDownload(selectedMediaEvents.at(0)); else bcApp->eventDownloadManager()->startMultipleEventDownloads(selectedMediaEvents); } else if (act == aSelectOnly || act == aSelectElse) { EventSourcesModel *sModel = qobject_cast<EventSourcesModel*>(m_sourcesView->model()); Q_ASSERT(sModel); if (!sModel) return; QSet<DVRCamera *> cameras = selectedCameraEvents.cameras(); QModelIndex sIdx = sModel->indexOfCamera(*cameras.begin()); if (act == aSelectOnly) { m_sourcesView->checkOnlyIndex(sIdx); // uncheck all, some kind of temporary hack foreach (DVRCamera *camera, cameras) sModel->setData(sModel->indexOfCamera(camera), Qt::Checked, Qt::CheckStateRole); } else { foreach (DVRCamera *camera, cameras) sModel->setData(sModel->indexOfCamera(camera), Qt::Unchecked, Qt::CheckStateRole); } } }
void LOS::processTrack(MidiTrack* track) { EventList* tevents = track->events(); if (tevents->empty()) return; //--------------------------------------------------- // Identify Parts // The MIDI tracks are broken up into parts // A new Part will be located based on track. // Events will be aligned on new track //--------------------------------------------------- PartList* pl = track->parts(); int lastTick = 0; for (iEvent i = tevents->begin(); i != tevents->end(); ++i) { Event event = i->second; int epos = event.tick() + event.lenTick(); if (epos > lastTick) lastTick = epos; } QString partname = track->name(); int len = song->roundUpBar(lastTick + 1); // p3.3.27 if (config.importMidiSplitParts) { int bar2, beat; unsigned tick; sigmap.tickValues(len, &bar2, &beat, &tick); int lastOff = 0; int st = -1; // start tick current part int x1 = 0; // start tick current measure int x2 = 0; // end tick current measure for (int bar = 0; bar < bar2; ++bar, x1 = x2) { ///x2 = sigmap.bar2tick(bar+1, 0, 0); x2 = sigmap.bar2tick(bar + 1, 0, 0); if (lastOff > x2) { // this measure is busy! continue; } iEvent i1 = tevents->lower_bound(x1); iEvent i2 = tevents->lower_bound(x2); if (i1 == i2) { // empty? if (st != -1) { MidiPart* part = new MidiPart(track); part->setTick(st); part->setLenTick(x1 - st); // printf("new part %d len: %d\n", st, x1-st); part->setName(partname); pl->add(part); st = -1; } } else { if (st == -1) st = x1; // begin new part //HACK: //lastOff: for (iEvent i = i1; i != i2; ++i) { Event event = i->second; if (event.type() == Note) { int off = event.tick() + event.lenTick(); if (off > lastOff) lastOff = off; } } } } if (st != -1) { MidiPart* part = new MidiPart(track); part->setTick(st); // printf("new part %d len: %d\n", st, x2-st); part->setLenTick(x2 - st); part->setName(partname); pl->add(part); } } else { // Just one long part... MidiPart* part = new MidiPart(track); //part->setTick(st); part->setTick(0); part->setLenTick(len); part->setName(partname); pl->add(part); } //------------------------------------------------------------- // assign events to parts //------------------------------------------------------------- for (iPart p = pl->begin(); p != pl->end(); ++p) { MidiPart* part = (MidiPart*) (p->second); int stick = part->tick(); int etick = part->tick() + part->lenTick(); iEvent r1 = tevents->lower_bound(stick); iEvent r2 = tevents->lower_bound(etick); int startTick = part->tick(); EventList* el = part->events(); for (iEvent i = r1; i != r2; ++i) { Event ev = i->second; int ntick = ev.tick() - startTick; ev.setTick(ntick); el->add(ev); } tevents->erase(r1, r2); } if (tevents->size()) printf("-----------events left: %zd\n", tevents->size()); for (iEvent i = tevents->begin(); i != tevents->end(); ++i) { printf("%d===\n", i->first); i->second.dump(); } // all events should be processed: assert(tevents->empty()); }
/** * \brief ocl::Image::copyTo Copies from this Image to the destination Image. * * The operation assumes that all data are valid and no synchronization is necessary (active Queue executes in-order). * The operation forces that all commands within the active Queue including this one are completed. * * \param queue is a command queue on which the command is executed. * \param src_origin is the 3D offset in bytes from which the Image is read. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. * \param dest is the Image into which the data is going to be copied. * \param dest_origin is the 3D offset in bytes from which the destionation Image is read. */ void ocl::Image::copyTo(const Queue &queue, size_t *src_origin, const size_t *region, const Image &dest, size_t *dest_origin, const EventList &list) const { TRUE_ASSERT(this->context() == dest.context(), "Context of this and dest must be equal"); TRUE_ASSERT(this->id() != dest.id(), "Image must not be equal this->id() " << this->id() << "; other.id " << dest.id()); TRUE_ASSERT(queue.context() == *this->context(), "Context of queue and this must be equal"); OPENCL_SAFE_CALL( clEnqueueCopyImage(queue.id(), this->id(), dest.id(), src_origin, dest_origin, region, list.size(), list.events().data(), NULL) ); OPENCL_SAFE_CALL( clFinish(this->activeQueue().id()) ); }
/*! \brief Blocks until all commands in this Queue are issued to the associated device and have completed. * * clFinish does not return until all previously queued commands in command_queue have been processed and completed. */ void ocl::Queue::barrier(const EventList& list ) const { OPENCL_SAFE_CALL( clEnqueueBarrierWithWaitList (this->id(), list.size(), list.events().data(), 0) ); }
/** * \brief ocl::Image::read Transfers data from this Image to the host memory. * * You can be sure that the data is read. * \param origin is the 3D offset in bytes from which the Image is read. * \param ptr_to_host_data must point to a memory location whith region bytes available. * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}. */ void ocl::Image::read(size_t *origin, void *ptr_to_host_data, const size_t *region, const EventList &list) const { TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0"); OPENCL_SAFE_CALL( clEnqueueReadImage(this->activeQueue().id(), this->id(), CL_TRUE, origin, region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), NULL) ); OPENCL_SAFE_CALL( clFinish(this->activeQueue().id()) ); }