I have a question about OpenCL the example listed in the following link :
OpenCL vector addition program
I replaced one old line with one new - actually reading strings as elements of array of pointers as stated in documentation.
const cl_uint NumberOfStrings = 1; // Works ONLY FOR just one string
const char* sourcearr[] = { source_str1 , source_str2, source_str3 }; // array pointers to strings
const size_t sourcesizearr[] = { source_size1 , source_size2, source_size3}; // pointers to string sizes
// new
cl_program program = clCreateProgramWithSource(context, NumberOfStrings , (const char**)&sourcearr, (const size_t*)&sourcesizearr, &ret);
// old
// cl_program program = clCreateProgramWithSource(context, 1 , (const char**)&source_str, (const size_t*)&source_size, &ret);
All is working for just one string. If I put the value of NumberOfStrings > 1 I get a bunch of zeroes again.
I do not understand what happens.
I was not albe to find an example of reading more that one string into memory. It is always 1.
Related
I'm working on an Arduino project where I need to build (and work with) a two-dimensional array at runtime. I've been poking around looking for a solution, but I've had no luck. I found an example of a dynamic one-dimentional array helper here: http://playground.arduino.cc/Code/DynamicArrayHelper, so i've been trying to adopt that code for my use. I created a library using the following code:
My Header file:
#ifndef Dynamic2DArray_h
#define Dynamic2DArray_h
#include "Arduino.h"
class Dynamic2DArray
{
public:
Dynamic2DArray( bool sorted );
//Add an integer pair to the array
bool add( int v1, int v2);
//Clear out (empty) the array
bool clear();
//Get the array item in the specified row, column
int getValue(int row, int col);
//Get the number of rows in the array
int length();
private:
int _rows;
void * _slots;
bool _sorted;
void _sort();
};
#endif
The library's code:
#include "Arduino.h"
#include "Dynamic2DArray.h"
#define ARRAY_COLUMNS 2
int _rows;
void * _slots;
bool _sorted;
Dynamic2DArray::Dynamic2DArray(bool sorted) {
//Set our local value indicating where we're supposed to
//sort or not
_sorted = sorted;
//Initialize the row count so it starts at zero
_rows = 0;
}
bool Dynamic2DArray::add( int v1, int v2) {
//Add the values to the array
//implementation adapted from http://playground.arduino.cc/Code/DynamicArrayHelper
//Allocate memory based on the size of the current array rows plus one (the new row)
int elementSize = sizeof(int) * ARRAY_COLUMNS;
//calculate how much memory the current array is using
int currentBufferSize = elementSize * _rows;
//calculate how much memory the new array will use
int newBufferSize = elementSize * (_rows + 1);
//allocate memory for the new array (which should be bigger than the old one)
void * newArray = malloc ( newBufferSize );
//Does newArray not point to something (a memory address)?
if (newArray == 0) {
//Then malloc failed, so return false
return false;
}
// copy the data from the old array, to the new array
for (int idx = 0; idx < currentBufferSize ; idx++)
{
((byte*)newArray)[idx] = ((byte *)_slots)[idx];
}
// free the original array
if (_slots != NULL)
{
free(_slots);
}
// clear the newly allocated memory space (the new row)
for (int idx = currentBufferSize; idx < newBufferSize; idx++)
{
((byte *)newArray)[idx] = 0;
}
// Store the number of rows the memory is allocated for
_rows = ++_rows;
// set the array to the newly created array
_slots = newArray;
//Free up the memory used by the new array
free(newArray);
//If the array's supposed to be sorted,
//then sort it
if (_sorted) {
_sort();
}
// success
return true;
};
int Dynamic2DArray::length() {
return _rows;
};
bool Dynamic2DArray::clear() {
//Free up the memory allocated to the _slots array
free(_slots);
//And zero out the row count
_rows = 0;
};
int Dynamic2DArray::getValue(int row, int col) {
//do we have a valid row/col?
if ((row < _rows) && (col < ARRAY_COLUMNS)) {
//Return the array value at that row/col
return _slots[row][col];
} else {
//No? Then there's nothing we can do here
return -1;
}
};
//Sorted probably doesn't matter, I can probably ignore this one
void _sort() {
}
The initial assignment of the _slots value is giving me problems, I don't know how to define it so this code builds. The _slots variable is supposed to point to the dynamic array, but I've got it wrong.
When I try to compile the code into my project's code, I get the following:
Arduino: 1.8.0 (Windows 10), Board: "Pro Trinket 3V/12MHz (USB)"
sketch\Dynamic2DArray.cpp: In member function 'int Dynamic2DArray::getValue(int, int)':
sketch\Dynamic2DArray.cpp:83:22: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]
return _slots[row][col];
^
Dynamic2DArray.cpp:83: error: 'void*' is not a pointer-to-object type
Can someone please help me fix this code? I've posted the files to https://github.com/johnwargo/Arduino-Dynamic-2D-Array-Lib.
The code you took was for a 1D dynamic array; the modifications for a 2D array are too tricky. Give up these horrors.
I think there is no reason you use dynamic array. You can assume that size max is ROW_MAX * COL_MAX, so you can define a static array int array[ROW_MAX][COL_MAX].
on one hand if you defined a dynamic array, you could free space when you dont use it anymore and take advantage of it for other work. I dont know if this is your case.
on the other hand if you define a static array (on UNO), you have 32kB available on program space, instead of 2kB available on RAM.
Because of the difference 32kB / 2kB, there are very few chances you can get bigger array with dynamic allocation.
At the bottom of the documentation on PROGMEM, it shows what looks like a wonderfully simple way to compile strings into the program .text segment:
The F() macro
When an instruction like:
Serial.print("Write something");
is used, the string to be printed is normally saved in RAM. If your sketch prints a lot of stuff on the Serial Monitor, you can easily fill the RAM. If you have free FLASH memory space, you can easily indicate that the string must be saved in FLASH using the syntax:
Serial.print(F("Write something that is stored in FLASH"));
However, I have had only bad luck getting this to compile.
#include <avr/pgmspace.h>
static const struct {short cmd; const char *txt;} cmds[] = {
{2, F("Hi")},
};
It complains with
t.c:3: error: initializer element is not constant
{2, F("hi")},
^
t.c:3: error: (near initialization for 'cmds[0].txt')
exit status 1
initializer element is not constant
Without the F macro, it compiles just fine.
{2, "Hi"},
Does anyone have experience getting this to work? I have like 10K of strings I'd like to get into the program space.
The F macro can only be used in executable parts of the code, not variable definitions. And because struct member can't have the PROGMEM attribute, you have to do it in two steps: declare each text string in PROGMEM, then use the PROGMEM address in the struct.
An array of structs can be in PROGMEM, too.
static const char cmd_0_txt[] PROGMEM = "Hello";
static const char cmd_1_txt[] PROGMEM = "World";
struct cmd_t {short cmd; const char *txt; }; // the struct type
// An array of structs in PROGMEM
static const cmd_t cmds[] PROGMEM = {
{2, cmd_0_txt},
{2, cmd_1_txt},
};
void setup()
{
Serial.begin( 9600 );
Serial.println( F("Test") );
for (uint8_t i=0; i < sizeof(cmds)/sizeof(cmds[0]); i++) {
// First, read the PROGMEM txt member (a pointer to the text)
const char *ptr = (const char *) pgm_read_word( &cmds[i].txt ); // cast required
// Next, read each text character from that PROGMEM location
for (;;) {
char c = pgm_read_byte( ptr++ );
if (!c)
break;
Serial.print( c );
}
Serial.println();
}
}
void loop()
{}
I am trying to get interact with the internal memory of the PIC24F16KA101 MCU. After reading the data-sheet and the discussion on this site (which offer a pretty helpful sample code)used in the project
Now if I put the code below the program work just fine, since I am able to read successfully the same value that I wrote previously. However if after writing I unplug the MCU and perform only a read of the EEPROOM it is not going to return the value written. What could be the problem here?. Why can I write and then read successfully but can not read after a power off?.
Thanks in advance to all for the help
Damian
int __attribute__ ((space(eedata))) ee_addr;
void EepSetup();
void EepErase(void);
int EepWrite(int index, int data);
int EepRead(int index);
int main(int argc, char** argv)
{
unsigned int data = 123;
unsigned int data_read = 0;
Init_UART1();
UART1WriteString("START EEPROM PROGRAM \n");
EepSetup();
UART1WriteString("WRITING DATA TO MEMORY \n");
EepWrite(1,data);
//if the code works, just comment the upper section and read eeprom after
//disconecting the power source
UART1WriteString("READING DATA FROM MEMORY \n");
data_read = EepRead(1);
UART1WriteString("Value Read: ");
UART1WriteInt(data_read,16);
UART1WriteString("\n");
__delay_ms(1000);
return (EXIT_SUCCESS);
}
void EepSetup(){
//Disable Interrupts For 5 instructions
asm volatile("disi #5");
//Issue Unlock Sequence
asm volatile("mov #0x55, W0 \n"
"mov W0, NVMKEY \n"
"mov #0xAA, W1 \n"
"mov W1, NVMKEY \n");
}
void EepErase(void) {
NVMCON = 0x4050; // Set up NVMCON to bulk erase the data EEPROM
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence and Start Erase Cycle
while(_WR)
;
}
int EepRead(int index){
unsigned int offset;
TBLPAG = __builtin_tblpage(&ee_addr); // Initialize EE Data page pointer
offset = __builtin_tbloffset(&ee_addr); // Initizlize lower word of address
offset += index * sizeof(int);
return __builtin_tblrdl(offset); // read EEPROM data
}
int EepWrite(int index, int data){
unsigned int offset;
NVMCON = 0x4004; // Set up NVMCON to erase one word of data EEPROM
TBLPAG = __builtin_tblpage(&ee_addr); // Initialize EE Data page pointer
offset = __builtin_tbloffset(&ee_addr); // Initizlize lower word of address
offset += index * sizeof(int);
__builtin_tblwtl(offset, data);
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence and Start Erase Cycle
while(_WR);
return (EXIT_SUCCESS);
}
I just figured out what the problem was, it happens that if you use the PICkit 3 with MPLABX you have to check an option in the programmer to preserve the EEPROM memory,so the code was functional, you just need to check the option of "Preserve EEPROM Memory" in the programmer settings. I hope this help others.
Cheers, Damian
I am having an issue with my OpenCL kernel. The input arguments are corrupt when they are passed to the kernel. What makes this strange is this same exact kernel executes flawlessly on mac osx. Once I started porting my code over to windows (windows 8 64-bit) I started having this issue.
I have provided an example using my camera struct. The x,y,z coordinates are defined as <0,0,200>. However, when they make it to my kernel they show as <0,-0.00132704, -0.00132704>.
I have a kernel that accepts two structs.
typedef struct{
cl_float d;
cl_float3 eye;
cl_float3 lookat;
cl_float3 u;
cl_float3 v;
cl_float3 w;
cl_float3 up;
}rt_cl_camera;
typedef struct {
float r;
float g;
float b;
} rt_cl_rgb;
I have slimmed down my kernel for the sake of testing. After tracking down the issues I noticed that my input paramaters were not coming over correctly. However, I have determined that my output is being passed back correctly.
__kernel void ray_trace_scene( __global rt_cl_rgb* output,
__global rt_cl_camera* camera,
const unsigned int pcount)
{
int pixel = get_global_id(0);
if(pixel < pcount){
output[pixel].r = camera->eye.x;
output[pixel].g = camera->eye.y;
output[pixel].b = camera->eye.z;
}// End Pixel computation
}//End kernel
I am creating my input buffer with the follwoing:
cl_mem cam_input;
cl_uint cam_error;
cam_input = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(rt_cl_camera), NULL, &cam_error);
I am also checking to make sure my buffer was created successfully with
if (cam_error != CL_SUCCESS || !cam_input) {
throw std::runtime_error(CLERROR_FAILED_DEVBUFF);
}
I then write my data into my buffer with the following.
cl_uint err = 0;
err = clEnqueueWriteBuffer(commands, cam_input, CL_TRUE, 0, sizeof(rt_cl_camera), cam_ptr, 0, NULL, NULL);
if (err != CL_SUCCESS) {
throw std::runtime_error("Failed to write camera");
}
and finally linking my argument for the appropriate command line slot. Please note that slot zero is being used for my output.
err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &cam_input);
and checking that everything was successful..
if (err != CL_SUCCESS) {
throw std::runtime_error(CLERROR_FAILED_CMDARGS);
}
I am not receiving any error messages from openCL at any step of the process. Has anyone run into this? Any help is greatly appreciated.
side note - At each step of the way I am printing out my local variables to make sure they are correct and valid before I pass them over to the GPU.
Looks an alignment/packing issue. Try using float4 instead of float3 in the struct, and move float d at the end.
#include <Windows.h>
void memfrob(void * s, size_t n)
{
char *p = (char *) s;
while (n-- > 0)
*p++ ^= 42;
}
int main()
{
memfrob("C:\\Program Files\\***\***\\***\***\\***", 30344);
}
There's my code. If you can't tell, I'm not sure what I'm doing. I've Googled for about an hour and I haven't seen an example of how to use memfrob(), which is probably why I'm so lost. I'm trying to pass it the name of the file and then the size of the file in bytes, but my program just crashes.
Alright, this is what I have right now:
#include <Windows.h>
#include <stdio.h>
int count = 0;
FILE* pFile = 0;
long Size = 0;
void *memfrob(void * s, size_t n)
{
char *p = (char *) s;
while (n-- > 0)
*p++ ^= 42;
return s;
}
int main()
{
fopen_s(&pFile, "C:\\Program Files\\CCP\\EVE\\lib\\corelib\\nasty.pyj", "r+");
fseek(pFile, 0, SEEK_END);
Size = ftell(pFile);
char *buffer = (char*)malloc(Size);
memset(buffer, 0, Size);
fread(buffer, Size, 1, pFile);
fclose(pFile);
memfrob(buffer, Size);
fopen_s(&pFile, "C:\\Program Files\\CCP\\EVE\\lib\\corelib\\nasty.pyj", "w+");
fwrite(buffer, Size, 1, pFile);
fclose(pFile);
}
In my debugger, it seems that fread is not writing anything to buffer, and my ending file is just 2A over and over, which is 00 xor'd with 42. So can I get another hint?
You need to pass memfrob a piece of memory containing the contents of the file, rather than the name of the file. It's crashing because you're passing in a buffer of read-only memory, and then trying to modify it.
Investigate the open and read I/O functions, or alternatively fopen and fread. Your mainline should look something like:
int main() {
// open file
// find size of file
// allocate buffer of that size
// read contents of file into the buffer
// close the file
// call memfrob on the buffer
// do what you want with the file
// free the buffer
}
Well, several things are wrong here.
The minor problem is that you're passing it the location of the file and not the file itself. Read up on how to do file I/O in C (this being a pretty good link).
The real problem is that you seem to think this is encryption. This doesn't really encrypt your file from anything but the most trivial security issues (such as someone randomly opening your file).