Opencl for C++, buffer.release() is protected member - c++

Im learning how to make simple opencl programs in C++ using Amd's app sdk and Khronos's header files for Opencl 1.2. I used the below example and it is working. But when I try to .release() the buffers in the end, I get an error message from compiler saying "cannot access protected member".
int problemSize=1024;
const char * kernelDerlenecek =
"__kernel void Toplam(__global float * v1, __global float * v2)"
"{"
" int i = get_global_id(0);"
" v2[i]=v1[i];"
"}";
cl::Context altYapi(CL_DEVICE_TYPE_GPU);
cl::Program::Sources kaynaklar;
kaynaklar.push_back(std::make_pair(kernelDerlenecek,strlen(kernelDerlenecek)));
cl::Program program(altYapi,kaynaklar);
std::vector<cl::Device> aygitlar=altYapi.getInfo<CL_CONTEXT_DEVICES>();
program.build(aygitlar);
cl::Kernel kernel(program,"Toplam");
cl::CommandQueue cmdQ(altYapi,aygitlar[0]);
std::vector<cl_float> input;
std::generate_n (std::back_inserter ( input ) , problemSize , rand) ;
cl::Buffer inputBuffer(altYapi, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(cl_float) * input.size(), &input[0]);
cl::Buffer outputBuffer(altYapi ,CL_MEM_WRITE_ONLY , sizeof(cl_float )* input.size()) ;
kernel.setArg(0,inputBuffer);
kernel.setArg(1,outputBuffer);
cl::NDRange Global(1024);
cl::NDRange Local(64);
cmdQ.enqueueNDRangeKernel(kernel,cl::NullRange,Global,Local);
float * output = (float *)malloc(1024*sizeof(float));
cmdQ.enqueueReadBuffer(outputBuffer,CL_TRUE,0,1024 * sizeof(cl_float),output);
for(int i=0;i<1024;i++)
{
printf(" %f \n ",output[i]);
}
free(output);
//inputBuffer.release(); <----- this is not accessible!!!
//inputBuffer.~Wrapper() <----- invalid destructor name!!!
So I searched for the structure of wrapper class of buffer and found that:
class Wrapper
{
public:
typedef T cl_type;
protected:
cl_type object_;
public:
Wrapper() : object_(NULL) { }
~Wrapper()
{
if (object_ != NULL) { release(); } //This is releasing, should I destroy myself?
}
Wrapper(const Wrapper<cl_type>& rhs)
{
object_ = rhs.object_;
if (object_ != NULL) { retain(); }
}
Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
{
if (object_ != NULL) { release(); }
object_ = rhs.object_;
if (object_ != NULL) { retain(); }
return *this;
}
cl_type operator ()() const { return object_; }
cl_type& operator ()() { return object_; }
protected:
cl_int retain() const
{
return ReferenceHandler<cl_type>::retain(object_);
}
cl_int release() const //<---yes, its true that I cannot access. Who can?
{
return ReferenceHandler<cl_type>::release(object_);
}
};
Question: How can I release the memory dedicated to buffers? Even the ~Wrapper() nor ~Memory() does not work because error says "invalid destructor name".
Maybe it destroys itself when function exits? This is in a dll and from a C# wrapper, its being called repeatedly so I need it to be released only when needed. Thanks.

It is good that the class Buffer handles itself the allocation and destruction.
If you want to allocate and destroy it manually just do this:
vector<cl::Buffer> mybuffer;
Then simply to create a memory zone:
mybuffer.push_back(cl::Buffer(/*constructor parameters*/));
To destroy it:
mybuffer.clear();
And the good thing is that if you forget to delete it, it will delete it automatically.

You can wrap it in a pointer, preferably a smart one, like so:
std::unique_ptr<cl::Buffer> myBuffer(new cl::Buffer(...));
Then if you want to manually delete the data, or replace the data with something else:
myBuffer.reset(new cl::Buffer(...));
This will delete the old data and replace it with the new one, keep the "reset()" blank if you want to just delete the old data.

Related

CString used on static method

I am stuck into a problem, and I will be very grateful if you help me.
I have a MDI, and in CDocument class, I have a struct:
CMyDoc.h
class CMyDoc : public CDocument
{
...
struct SRecord
{
SRecord(){}
virtual ~SRecord(){}
CString sName;
CString sState;
CString sDateu;
CString sDatec;
};
CTypedPtrArray<CPtrArray, SRecord*> m_arrRecord;
and somewhere I load this struct with data:
SRecord* pItem = new SRecord;
pItem->sName = saItem.GetAt(ML_ASSETNAME);
pItem->sState = saItem.GetAt(ML_STATE);
pItem->sDateu = saItem.GetAt(ML_DATEU;
pItem->sDatec = saItem.GetAt(ML_DATEC);
m_arrRecord.Add(pItem);
ok. I am trying to sort data:
void CMyDoc::SortData(int nColumn, BOOL bAscending)
{
switch(nColumn)
{
case 9:
if(bAscending)qsort((void*)m_arrRecord.GetData(), m_arrRecord.GetSize(), sizeof(SRecord), CompareDateUAscending);
else qsort((void*)m_arrRecord.GetData(), m_arrRecord.GetSize(), sizeof(SRecord), CompareDateUDescending);
break;
...
}
but the problem become when data is access in static method:
int CMyDoc::CompareDateUDescending(const void* arg1, const void* arg2)
{
SRecord* Record1 = (SRecord*)arg1;
SRecord* Record2 = (SRecord*)arg2;
if(Record1->sDateu.IsEmpty() || Record2->sDateu.IsEmpty()) // <--- crash !
return 0;
COleDateTime dL, dR;
dL.ParseDateTime(Record1->sDateu);
dR.ParseDateTime(Record2->sDateu);
return (dL == dR ? 0 : (dL < dR ? 1 : -1));
}
and the crash take me here (atlsimpstr.h):
CStringData* GetData() const throw()
{
return( reinterpret_cast< CStringData* >( m_pszData )-1 ); // the crash lead me on this line
}
what I am doing wrong ?
Any help will be very appreciated !
Update:
I have tried this:
int CMyDoc::CompareDateUDescending(const void* arg1, const void* arg2)
{
SRecord* Record1 = *(SRecord**)arg1; // <-- OK
SRecord* Record2 = *(SRecord**)arg2; // <-- Unhandled exception* see note below
if(Record1->sDateu.IsEmpty() || Record2->sDateu.IsEmpty())
return 0;
COleDateTime dL, dR;
dL.ParseDateTime(Record1->sDateu);
dR.ParseDateTime(Record2->sDateu);
return (dL == dR ? 0 : (dL < dR ? 1 : -1));
}
and the crash told me:
"An unhandled exception was encountered during a user callback." strange ...
The qsort comparison function receives pointers to the elements in the array. But since the elements in the array are themselves pointers what your specific function receives as arguments are pointers to pointers to SRecord, i.e. SRecord**.
You can solve it by doing e.g.
const SRecord* Record1 = *reinterpret_cast<const SRecord**>(arg1);
That is, you cast arg1 to SRecord** and then dereference that pointer to get a SRecord*.
Example on how to use the C++ standard sort function.
First you need to update your comparison function a little:
// The comparison function should return true if Record1 is *smaller* than Record2,
// and return false otherwise
bool CMyDoc::CompareDateUDescending(const SRecord* Record1, const SRecord* Record2)
{
return Record1->sDateu < Record2->sDateu;
}
Then to call sort:
std::sort(m_arrRecord.GetData(), m_arrRecord.GetData() + m_arrRecord.GetSize(), CompareDateUDescending);
Much simpler!

v8 create object without methods

I'm work on next version of v8-profiler and now I want to simplify it.
I see that my class (ProfileNode) don't needs hidden link to internal object (v8::CpuProfileNode), because my class don't uses internal object methods.
Can I delete getter methods and replace it like the example below?
Is it wrong realisation?
Is it hight memory usage?
Or it's OK?
(I'm novice in c++ and v8 library)
(Please ignore version uncompatibility - it's not a part of question)
This is a part of current profile_node.cc
Persistent<ObjectTemplate> ProfileNode::node_template_;
void ProfileNode::Initialize() {
Local<ObjectTemplate> tpl = NanNewLocal<ObjectTemplate>(ObjectTemplate::New());
NanAssignPersistent(ObjectTemplate, node_template_, tpl);
tpl->SetInternalFieldCount(1);
tpl->SetAccessor(String::New("functionName"), ProfileNode::GetFunctionName);
...
}
NAN_GETTER(ProfileNode::GetFunctionName) {
NanScope();
Local<Object> self = args.Holder();
void* ptr = NanGetInternalFieldPointer(self, 0);
Handle<String> fname = static_cast<CpuProfileNode*>(ptr)->GetFunctionName();
NanReturnValue(fname);
}
...
Handle<Value> ProfileNode::New(const CpuProfileNode* node) {
NanScope();
if (node_template_.IsEmpty()) {
ProfileNode::Initialize();
}
if(!node) {
return Undefined();
}
else {
Local<Object> obj = NanPersistentToLocal(node_template_)->NewInstance();
NanSetInternalFieldPointer(obj, 0, const_cast<CpuProfileNode*>(node));
return obj;
}
}
After refactoring
//ProfileNode::Initialize deleted
//ProfileNode::GetFunctionName deleted
Handle<Value> ProfileNode::New(const CpuProfileNode* node) {
NanScope();
if(!node) {
return NanUndefined();
}
else {
//Create new simplest object, instead of new instance of object template
Local<Object> obj = NanNew<Object>();
//Append the value to this object
obj->Set(String::New("functionName"), node->GetFunctionName());
//Delete internal link.
//NanSetInternalFieldPointer(obj, 0, const_cast<CpuProfileNode*>(node));
return obj;
}
}

boost::ptr_map<> and _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) assertion failures

first question on stackoverflow, was hoping to get some help with this issue. If you take a look at the following EffectManager class, I am getting an assertion failure on _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) when an effectmanager instance is deallocated.
It has something to do with trying to free the memory of the effectsmap, if I never insert the effect into the map I don't run into this problem.
it will also work fine if I use a base STL map, ie
typedef std::map<std::wstring, ID3DXEffect*> EffectsMap;
class EffectManager
{
public:
typedef boost::ptr_map<std::wstring, ID3DXEffect> EffectsMap;
EffectManager();
~EffectManager();
void init();
ID3DXEffect *loadEffect(LPDIRECT3DDEVICE9 d3ddev, std::wstring effectfile);
private:
std::shared_ptr<EffectsMap> effects_;
};
EffectManager::EffectManager() : effects_(NULL)
{
}
EffectManager::~EffectManager()
{
for(auto it = effects_->begin(); it != effects_->end(); it++){
it->second->Release();
}
}
void EffectManager::init()
{
effects_ = std::shared_ptr<EffectsMap>(new EffectsMap());
}
ID3DXEffect *EffectManager::loadEffect(LPDIRECT3DDEVICE9 d3ddev, std::wstring effectfile)
{
if(!effects_)
return NULL;
ID3DXEffect *effect;
if(effects_->count(effectfile)){
effect = effects_->find(effectfile)->second;
} else {
D3DXCreateEffectFromFile(d3ddev, effectfile.c_str(), NULL, NULL, D3DXFX_NOT_CLONEABLE, NULL, &effect, NULL);
effects_->insert(effectfile, effect);
}
return effect;
}

Keeping the downloaded torrent in memory rather than file libtorrent

Working with Rasterbar libtorrent I dont want the downloaded data to sit on my hard drive rather a pipe or variable or something Soft so I can redirect it to somewhere else, Mysql, or even trash if it is not what I want, is there anyway of doing this in preferably python binding if not in C++ using Libtorrent?
EDIT:--> I like to point out this is a libtorrent question not a Linux file handling or Python file handling question. I need to tell libtorrent to instead of save the file traditionally in a normal file save it to my python pipe or variable or etc.
You can do this by implementing your own storage class to use with libtorrent. Unfortunately this is not possible to do in python, but you can do it in c++. The documentation for it is a bit scarce and can be found here.
Here's a simple example of how to do this by storing all the data in RAM:
struct temp_storage : storage_interface
{
temp_storage(file_storage const& fs) : m_files(fs) {}
virtual bool initialize(bool allocate_files) { return false; }
virtual bool has_any_file() { return false; }
virtual int read(char* buf, int slot, int offset, int size)
{
std::map<int, std::vector<char> >::const_iterator i = m_file_data.find(slot);
if (i == m_file_data.end()) return 0;
int available = i->second.size() - offset;
if (available <= 0) return 0;
if (available > size) available = size;
memcpy(buf, &i->second[offset], available);
return available;
}
virtual int write(const char* buf, int slot, int offset, int size)
{
std::vector<char>& data = m_file_data[slot];
if (data.size() < offset + size) data.resize(offset + size);
std::memcpy(&data[offset], buf, size);
return size;
}
virtual bool rename_file(int file, std::string const& new_name) { assert(false); return false; }
virtual bool move_storage(std::string const& save_path) { return false; }
virtual bool verify_resume_data(lazy_entry const& rd, error_code& error) { return false; }
virtual bool write_resume_data(entry& rd) const { return false; }
virtual bool move_slot(int src_slot, int dst_slot) { assert(false); return false; }
virtual bool swap_slots(int slot1, int slot2) { assert(false); return false; }
virtual bool swap_slots3(int slot1, int slot2, int slot3) { assert(false); return false; }
virtual size_type physical_offset(int slot, int offset) { return slot * m_files.piece_length() + offset; };
virtual sha1_hash hash_for_slot(int slot, partial_hash& ph, int piece_size)
{
int left = piece_size - ph.offset;
TORRENT_ASSERT(left >= 0);
if (left > 0)
{
std::vector<char>& data = m_file_data[slot];
// if there are padding files, those blocks will be considered
// completed even though they haven't been written to the storage.
// in this case, just extend the piece buffer to its full size
// and fill it with zeroes.
if (data.size() < piece_size) data.resize(piece_size, 0);
ph.h.update(&data[ph.offset], left);
}
return ph.h.final();
}
virtual bool release_files() { return false; }
virtual bool delete_files() { return false; }
std::map<int, std::vector<char> > m_file_data;
file_storage m_files;
};
You'd also need a constructor function to pass in through the add_torrent_params struct when adding a torrent:
storage_interface* temp_storage_constructor(
file_storage const& fs, file_storage const* mapped
, std::string const& path, file_pool& fp
, std::vector<boost::uint8_t> const& prio)
{
return new temp_storage(fs);
}
From this point it should be fairly straight forward to store it in a MySQL database or any other back-end.
If you're on Linux, you could torrent into a tmpfs mount; this will avoid writing to disk. That said, this obviously means you're storing large files in RAM; make sure you have enough memory to deal with this.
Note also that most Linux distributions have a tmpfs mount at /dev/shm, so you could simply point libtorrent to a file there.
I've implemented a torrent client in Go just for this purpose. I wanted to able to handle and control the data directly, for use in writing torrentfs, and to have storage backends to S3 and various databases.
It would be trivial to plug in an in-memory storage backend to this client.
Try giving the library a cStringIO "file handle" instead of a real file handle. That works for most python libraries.

Valgrind reports "Invalid free() / delete / delete[]"

I'm not sure what could be causing this.
==18270== Invalid free() / delete / delete[]
==18270== at 0x400576A: operator delete(void*) (vg_replace_malloc.c:342)
==18270== by 0x80537F7: LCD::LCDControl::~LCDControl() (LCDControl.cpp:23)
==18270== by 0x806C055: main (Main.cpp:22)
==18270== Address 0x59e92c4 is 388 bytes inside a block of size 712 alloc'd
==18270== at 0x40068AD: operator new(unsigned int) (vg_replace_malloc.c:224)
==18270== by 0x8078033: LCD::DrvCrystalfontz::Get(std::string, LCD::LCDControl*, Json::Value*, std::string) (DrvCrystalfontz.cpp:652)
==18270== by 0x8053F50: LCD::LCDControl::ConfigSetup() (LCDControl.cpp:71)
==18270== by 0x80539F7: LCD::LCDControl::Start(int, char**) (LCDControl.cpp:31)
==18270== by 0x806C025: main (Main.cpp:21)
Here's LCDControl's destructor where delete is called.
LCDControl::~LCDControl() {
Shutdown();
for(std::vector<std::string>::iterator it = display_keys_.begin();
it != display_keys_.end(); it++) {
Error("Deleting %s %p", (*it).c_str(), devices_text_[*it]);
if(devices_text_.find(*it) != devices_text_.end() && devices_text_[*it])
delete devices_text_[*it]; // line 23
}
//delete app_;
}
Here's Crystalfontz::Get()
switch(m->GetProtocol()) {
case 1:
return new Protocol1(name, m, v, config);
break;
case 2:
return new Protocol2(name, m, v, config); // line 652
break;
case 3:
return new Protocol3(name, m, v, config, scab);
break;
default:
Error("Internal error. Model has bad protocol: <%s>",
m->GetName().c_str());
break;
devices_text_:
std::map<std::string, Generic <LCDText>*> devices_text_;
LCDControl::ConfigSetup(),
void LCDControl::ConfigSetup() {
if(!CFG_Get_Root()) return;
Json::Value::Members keys = CFG_Get_Root()->getMemberNames();
for(std::vector<std::string>::iterator it = keys.begin(); it != keys.end(); it++ ) {
if(it->find("display_", 0) != std::string::npos) {
Json::Value *display = CFG_Fetch_Raw(CFG_Get_Root(), it->c_str());
Json::Value *driver = CFG_Fetch_Raw(display, "driver");
if(!driver) {
Error("CFG: Must specify driver <%s>", it->c_str());
continue;
}
Json::Value *rows = CFG_Fetch_Raw(display, "rows", new Json::Value(-1));
/*if(!rows->isNumeric() || rows->asInt() == -1) {
Error("Display <%s> requires number of rows to initialize.", it->c_str());
delete display;
delete driver;
continue;
}*/
Json::Value *cols = CFG_Fetch_Raw(display, "cols", new Json::Value(-1));
/*if(!cols->isNumeric() || rows->asInt() == -1) {
Error("Display <%s> requires number of columns to initialize.", it->c_str());
delete display;
delete driver;
delete rows;
continue;
}*/
Json::Value *model = CFG_Fetch_Raw(display, "model");
if(driver->asString() == "crystalfontz") {
if(model) {
devices_text_[*it] = DrvCrystalfontz::Get(*it, this,
CFG_Get_Root(), model->asString()); // line 71
} else {
Error("Device <%s> requires a model.", it->c_str());
delete display;
delete driver;
delete rows;
delete cols;
continue;
}
} else if(driver->asString() == "qt") {
devices_text_[*it] = new DrvQt(*it, this, CFG_Get_Root(),
rows->asInt(), cols->asInt());
} else if(driver->asString() == "pertelian") {
//devices_text_[*it] = new DrvPertelian(this, CFG_Get_Root(), rows->asInt(), cols->asInt());
} else
continue;
if(model) delete model;
delete display;
delete driver;
delete rows;
delete cols;
}
}
for(std::map<std::string, Generic<LCDText> *>::iterator it =
devices_text_.begin(); it != devices_text_.end(); it++) {
display_keys_.push_back(it->first);
Error("Starting <%s> %p", it->first.c_str(), it->second);
Generic<LCDText> *device = it->second;
device->CFGSetup(it->first);
device->Connect();
device->SetupDevice();
device->BuildLayouts();
device->StartLayout();
}
}
I'm guessing that Protocol1 et al. are subclasses of some SuperProtocol?
devices_text_[*it] goes through assuming that it contains something of type SuperProtocol, so delete devices_text_[*it] calls SuperProtocol::~ SuperProtocol().
However, what you really want to call is Protocol1::~Protocol1() if you're destructing a Protocol1; this only works if you mark SuperProtocol::~ SuperProtocol() as virtual.
Instead of going through the keys, finding it in the map, then deleting it, why not just iterate through the map deleting as you go? I'd make a functor and use for_each (this isn't a guideline or anything, just my opinion),
typedef Generic<LCDText> GenericLCDText;
typedef std::map<std::string, GenericLCDText*> GenericLCDTextMap;
typedef GenericLCDTextMap::value_type GenericLCDTextPair;
struct device_text_deleter : std::unary_function<const GenericLCDTextPair&, void>
{
void operator()(const GenericLCDTextPair& pPair)
{
Error("Deleting %s %p", pPair.first.c_str(), pPair.second);
delete pPair.second;
}
}
std::for_each(devices_text_.begin(), devices_text_.end(), device_text_deleter());
_devices.text_.clear(); // optional, removes the deleted pointers. unnecessary
// if this is run in the destructor, since map goes away
// shortly after
That said, you're code would be improved by the following:
// typedef's for readability (would be in header, maybe private)
typedef std::vector<std::string> StringVector;
typedef Generic<LCDText> GenericLCDText;
typedef std::map<std::string, GenericLCDText*> GenericLCDTextMap;
for(StringVector::iterator it = display_keys_.begin();
it != display_keys_.end(); it++)
{
// find first! otherwise you're looking up the pair every time
GenericLCDTextMap::iterator pair = devices_text_.find(*it);
if (p != devices_text_.end())
{
// operator-> is overloaded for iterators but might as well use
// the pair now.
Error("Deleting %s %p", pair->first.c_str(), pair->second);
// no need to check for null, delete null is a-ok
delete pair->second;
}
}
Hopefully this will make it easier to spot the errors. Make sure any base classes you use have virtual destructors.
Check you haven't added a string in the vector twice (this would be "fixed" buy just iterating through the map, though you'll want to find out why duplicates exist in the first place), etc.
I've never tried this before, but maybe add a double delete macro thing (totally untested):
#define DOUBLE_DELETE_GAURD static bool x = false; assert(x == false); x = true;
Then just add it to your destructor. If you double delete, and the static bool is still around, the assertion will fail. This is completely in undefined la-la land, though.
Could it be that
display_keys_ contains the same string more than once and
this string has an associated Generic <LCDText>* in devices_text_?
In this case the pointer would be given to delete twice and this isn't legal...