OpenCL device memory read/write issue - opencl

I am using TI's Keystone II which has ARM as host and 8 accelerator DSP cores. These DSP cores don't talk to each other as they do not have any shared memory with them.
I am getting this strange issue that I am unable to rewrite into this 'cum' array in which I am computing the cumulative frequency. I am only able to read whatever I wrote to it the first time. The writes after that are not registered.
Any solutions to this issue?
The device has a Unified Memory architecture. Also 'cum' and 'frequency' are of 'CL_MEM_READ_WRITE' type.
This code snippet runs on the DSP cores
...
//upscan
for(i=0; i < 32; i++)
{
if(pid<4)
{
localvar1 = frequency[(i*8)+(2*pid)];
localvar2 = frequency[(i*8)+(2*pid)+1];
cum[(i*8)+(2*pid)+1] = localvar1 + localvar2;
}
}
for(i=0; i < 32; i++)
{
if(pid<2)
{
localvar1 = cum[(i*8)+(4*pid)+3];
localvar2 = cum[(i*8)+(4*pid)+1];
cum[(i*8)+(4*pid)+3] = localvar1 + localvar2;
}
}
for(i=0; i < 32; i++)
{
if(pid<1)
{
localvar1 = cum[(i*8)+(pid)+7];
localvar2 = cum[(i*8)+(pid)+3];
cum[(i*8)+(pid)+7] = localvar1 + localvar2;
}
}
...

use a barrier or mem_fence between your for-loops, the exact flags choice depends on the type of memory you're using (global, local) and device specific details but a barrier should solve your problem.

Related

MSVC2022 17.2 address sanitizer trigger false positive on vector::push_back

I turned on Asan on my project, which is a exe project and based on webRTC.lib(release72).
Because webRTC release72 do not support Asan on windows, so the webRTC.lib can not turn on Asan, BTW, the webRTC.lib is generated by MSVC2017 while my project is generated by MSVC2022(17.2 preview).
Before I turned on Asan on my project, it works normally. then I turned on Asan, my project trigger a Asan report in webRTC h264 EncoderQueue thread:
std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length) {
std::vector<uint8_t> out;
for (size_t i = 0; i < length;) {
// Be careful about over/underflow here. byte_length_ - 3 can underflow, and
// i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
// above, and that expression will produce the number of bytes left in
// the stream including the byte at i.
if (length - i >= 3 && !data[i] && !data[i + 1] && data[i + 2] == 3) {
// Two rbsp bytes.
out.push_back(data[i++]);
out.push_back(data[i++]);
// Skip the emulation byte.
i++;
} else {
// Single rbsp byte.
out.push_back(data[i++]);<======crash here everytime
}
}
return out;
}

How to change volume of an audio AVPacket

I have a desktop Qt-based application that fetches a sound stream from the network and plays it using QAudioOutput. I want to provide a volume control to the user so that he can reduce the volume. My code looks like this:
float volume_control = get_user_pref(); // user provided volume level {0.0,1.0}
for (;;) {
AVPacket *retrieved_pkt = get_decoded_packet_stream(); // from network stream
AVPacket *work_pkt
= change_volume(retrieved_pkt, volume_control); // this is what I need
// remaining code to play the work_pkt ...
}
How do I implement change_volume() or is there any off the shelf function that I can use?
Edit: Adding codec-related info as requested in the comments
QAudioFormat format;
format.setFrequency(44100);
format.setChannels(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
The following code works just fine.
// audio_buffer is a byte array of size data_size
// volume_level is a float between 0 (silent) and 1 (original volume)
int16_t * pcm_data = (int16_t*)(audio_buffer);
int32_t pcmval;
for (int ii = 0; ii < (data_size / 2); ii++) { // 16 bit, hence divided by 2
pcmval = pcm_data[ii] * volume_level ;
pcm_data[ii] = pcmval;
}
Edit: I think there is a significant scope of optimization here, since my solution is compute-intensive. I guess avcodec_decode_audio() can be used to speed it up.

How to read the weight from a Weight USB Scale

I have a USB weighing from stamps.com (Model 510: http://www.stamps.com/postage-online/digital-postage-scales/)
I was able to find the drivers to make it stand alone online, but my next question is how do I read the weight of the object on the scale in my classic ASP page / VBScript.
Does anyone have any suggestions where I should begin my search?
I'm not sure if this is applicable to your specific model but there's an article at http://nicholas.piasecki.name/blog/2008/11/reading-a-stamps-com-usb-scale-from-c-sharp/ where the author has written C# code to read from the scale because it conforms to basic USB HID (human input device) standards. The author made use of Mike OBrien's HID library https://github.com/mikeobrien/HidLibrary
They start off getting the raw bytes:
HidDeviceData inData;
HidDevice[] hidDeviceList;
HidDevice scale;
hidDeviceList = HidDevices.Enumerate(0x1446, 0x6A73);
if (hidDeviceList.Length > 0)
{
int waitTries;
scale = hidDeviceList[0];
waitTries = 0;
scale.Open();
if (scale.IsConnected)
{
inData = scale.Read(250);
for (int i = 0; i < inData.Data.Length; ++i)
{
Console.WriteLine("Byte {0}: {1:X}", i, inData.Data[i]);
}
}
scale.Close();
scale.Dispose();
}
Then go on to reverse engineer the payload and construct a function to get the weight in ounces:
private void GetStampsComModel2500iScaleWeight(out decimal? ounces, out bool? isStable)
{
HidDeviceData inData;
HidDevice[] hidDeviceList;
HidDevice scale;
isStable = null;
ounces = null;
hidDeviceList = HidDevices.Enumerate(0x1446, 0x6A73);
if (hidDeviceList.Length > 0)
{
int waitTries;
scale = hidDeviceList[0];
waitTries = 0;
scale.Open();
// For some reason, the scale isn't always immediately available
// after calling Open(). Let's wait for a few milliseconds before
// giving up.
while (!scale.IsConnected && waitTries < 10)
{
Thread.Sleep(50);
waitTries++;
}
if (scale.IsConnected)
{
inData = scale.Read(250);
ounces = (Convert.ToDecimal(inData.Data[4]) +
Convert.ToDecimal(inData.Data[5]) * 256) / 10;
isStable = inData.Data[1] == 0x4;
}
scale.Close();
scale.Dispose();
}
}
In order to read the weight from your classic ASP page/VBScript (on the server, right?) the easiest solution looks to be turning the working C# class into a COM component. There are tutorials you can follow to create the C# COM Component and register it on the server, then you would call it from VBScript like:
Dim app
Set app = Server.CreateObject("MyScaleComponent")

OutOfMemoryError during heuristic search

I'm writing a program to solve an 8 tile sliding puzzle for an AI class. in theory this is pretty easy, but the number of node states generated is pretty large (estimated 180,000 or so). We're comparing different heuristic functions in class, so my code has to be able to handle even some very inefficient functions. I'm getting "OutOfMemoryError: Java heap space" when using java's PriorityQueue class. Heres the relevant code withing my solver function: (the error is on the openList.add(temp); line)
public void solve(char[] init,int searchOrder)
{
State initial = new State(init,searchOrder); //create initial state
openList = new PriorityQueue<State>(); //create open list
closedList = new LinkedList<State>(); // create closed list
generated = new HashSet(); //Keeps track of all nodes generated to cut down search time
openList.add(initial); //add initial state to the open list
State expanded,temp = null,solution = null; //State currently being expanded
int nodesStored = 0, nodesExpanded = 0;
boolean same; //used for checking for state redundancy
TreeGeneration:
while(openList.size() > 0)
{
expanded = openList.poll();
closedList.addLast(expanded);
for (int k = 0; k < 4; k++)
{
if (k == 0)
{
temp = expanded.moveLeft();
}
else if (k == 1)
{
temp = expanded.moveRight();
}
else if (k == 2)
{
temp = expanded.moveAbove();
}
else
{
temp = expanded.moveBelow();
}
if(temp.isSolution())
{
solution = temp;
nodesStored = openList.size() + closedList.size();
nodesExpanded = closedList.size();
break TreeGeneration;
}
if(!generated.contains(temp))
{
// System.out.println(temp.toString());
openList.add(temp); // error here
generated.add(temp);
}
// System.out.println(openList.toString());
}
}
Am I doing something wrong here, or should I be using something else to handle this quantity of data? Thanks.
By default, JVM starts with 64 MB heap space, you can increase this amount by passing a parameter like below;
java -Xmx1024m YOUR_CLASS
this gives 1024 MB heap space in memory, you can change the amount of memory as you need.
If you are using NetBeans, Netbeans doesn't scale heap space automatically, you can achieve this by following below steps;
1- Right click on your project
2- Navigate to Set Configuration -> Customize
3-Add -Xmx256m into VM Options then click Ok
Now, you can run your project with custom heap space.

send integer in Qt

anyone can tell me how to open a TCP connection and send data at the same time?
I open the connection as follows:
socket-> conectohost (host, port)
I would like to send along with the order to open connection 6 integers.
thank you very much
As far as I know, you need to wait for the connection to be established before you can send data via QTcpSocket. Would a combination like this work in your usecase?
socket->connectToHost(...);
if( socket->waitForConnected() ) {
socket->write("my_data");
}
int array[] = {1,2,3,4,5,6};
int array_elements = sizeof(array) / sizeof(int);
socket->connectToHost("example.com", 12345);
if(socket->waitForConnected(1000)) {
qDebug("Connected.");
for(int n = 0; n < array_elements; n++)
socket->write((char*)(array + n * sizeof(int)), sizeof(int));
qDebug("6 integers sent. Eat that.");
socket->disconnectFromHost();
} else {
qDebug("Timeout.");
}

Resources