CUDA - check repeated values and add two values - c++

I have two group of arrays
a1 a2 a3 a4 a5 a6 a7 a8 <= name it as key1
b1 b2 b3 b4 b5 b6 b7 b8 <= val1
c1 c2 c3 c4 c5 c6 c7 c8
and
d1 d2 d3 d4 d5 d6 d7 d8 <= key2
e1 e2 e3 e4 e5 e6 e7 e8 <= val2
f1 f2 f3 f4 f5 f6 f7 f8
The arrays a1,...,an and d1,...,dn are sorted and might be repeated. i.e. their values might be something like 1 1 2 3 4 6 7 7 7 ... I want to check if for each Tuple di,ei check if it is equal to any of ai,bi. If it is (di==ai,bi==ei) then I have to combine fi and ci using some function e.g. add and store in fi.
Firstly, is it possible to do this using zip iterators and transformation in thurst library to solve this efficiently?
Secondly, the simplest method that I can imagine is to count occurance of number of each keys (ai) do prefix sum and use both to get start and end index of each keys and then for each di use above counting to iterate through those indices and check if ei==di. and perform the transformation.
i.e. If I have
1 1 2 3 5 6 7
2 3 4 5 2 4 6
2 4 5 6 7 8 5
as first array, I count the occurance of 1,2,3,4,5,6,7,...:
2 1 1 0 1 1 1 <=name it as count
and then do prefix sum to get:
2 3 4 4 5 6 7 <= name it as cumsum
and use this to do:
for each element di,
for i in (cumsum[di] -count[di]) to cumsum[di]:
if ei==val1[i] then performAddition;
What I fear is that since not all threads are equal, this will lead to warp divergence, and I may not have efficient performance.

You could treat your data as two key-value tables.Table1: (a,b) -> c and Table2: (d,e)->f, where pair (a,b) and (d,e) are keys, and c, f are values.
Then your problem simplifies to
foreach key in Table2
if key in Table1
Table2[key] += Table1[key]
Suppose a and b have limited ranges and are positive, such as unsigned char, a simple way to combine a and b into one key is
unsigned short key = (unsigned short)(a) * 256 + b;
If the range of key is still not too large as in the above example, you could create your Table1 as
int Table1[65536];
Checking if key in Table1 becomes
if (Table1[key] != INVALID_VALUE)
....
With all these restrictions, implementation with thrust should be very simple.
Similar combining method could still be used if a and b have larger range like int.
But if the range of key is too large, you have to go to the method suggested by Robert Crovella.

Related

Grouping lines with same leading word using Javascript Regex Engine

Suppose you have the following multi-line string:
C1 10
C2 20
C3 30
C2 40
C4 50
C3 60
And you want to match only those lines which have the same leading word, so as to build the following result:
C1 10
C2 20 40
C3 30 60
C4 50
I am trying to figure out a solution with pure Regex, but I am stuck. Any help?
I did try what the regex that follows, but it didn't work...
Regex: /(^\w+\b)(.*$)([\s\S]*?\n)(\1)(.*$)/gm
Substitution:$1$2$5$3
Result:
C1 10
C2 20 40
C3 30
C4 50
C3 60
As you can see, it only works with the first occurrence, despite the fact that I have used a lazy quantifier in the third capturing group.
Any help?
You could also accomplish this using reduce()
const data = `C1 10
C2 20
C3 30
C2 40
C4 50
C3 60`;
const result = data.split("\n").reduce((acc, val) => {
const vals = val.split(" ");
if (!acc[vals[0]]) acc[vals[0]] = vals[1];
else acc[vals[0]] += ` ${vals[1]}`;
return acc;
}, {});
console.log(result);

print and save matrix in fortran

Hello everyone I am new to Fortran and I am facing a problem. Let s assume I have a matrix a(5,50)
a1 a2 a3 a4 a5 a6 a7 etc
b1 b2 b3 b4 b5 b6 b7 etc
c1 c2 c3 c4 c5 c6 c7 etc
d1 d2 d3 d4 d5 d6 d7 etc
e1 e2 e3 e4 e5 e6 e7 etc
is there a way to save it into a file and print the matrix like the following
a1 b1 c1 d1 e1
a2 b2 c2 d2 e2
a3 b3 c3 d3 e3
etc
without saving it to another matrix? Because ok i can always do a loop and save it to a new matrix and then save that to a file and print it. I have also created a subroutine to print my matrix in a correct order and be presentable
Sure.
You could loop over the first index, then write the whole column:
do ii = 1, 50
write(unit, '(5(I7))') a(ii, :)
end do
Or you could use transpose:
write(unit, '(5(I7))') transpose(a)
(I'm assuming that a is an integer array and that all values can be written with 6 or fewer digits (including sign). Change the format if that's not the case.)
This computer doesn't have a fortran compiler, so I haven't tested it, but it should work.
Cheers

Compare and merge vector elements C++

I have a (somewhat) basic question. I have a vector with string elements of the following type:
1 X 2
1 X 4
1 X 7
2 Y 1
2 Y 3
3 X 4
3 X 12
.....
etc
Now what I want to do is to merge the elements that have the same starting coefficient and append "00" until I have 6 integer elements after X,Y etc so my output would be:
1 X 2 4 7 00 00 00
2 Y 1 3 00 00 00 00
3 X 4 12 00 00 00 00
.....
I've tried iterating over my vector and comparing my elements with find() and adding them to another vector but it doesn't work. I'm not super comfortable with vectors so any ideas would be appreciated! :)

Reading bytes from a binary file

I have got a binary file and i need to store from ( x, y ) position z amount of bytes. For example I have got this sequence of bytes :
00000000 49 49 49 49 05 00 00 00 08 00 00 00 1a 00 00 00 | y0
00000010 39 a6 82 f8 47 8b b8 10 78 97 f1 73 56 d9 6f 00 | y1
00000020 58 99 d5 3b ac 7b 7b 40 b6 2e 9f 0a 69 b2 ac a0 | y2
________________________________________________________________
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15
Every 2 merged numbers represents 1 byte ( it's taken from hexdump -C - coding is a little endian ). 49 = 1 byte, f8 is 1 byte etc ...
( x , y ) means position. For example if i put for x = 2,y = 2 i get position ( 2, 2 ) that means i start reading bytes from position y2, x2. In this case i start at byte d5 If i put z = 3 that means i want to store 3 bytes in this case those bytes are d5, 3b, ac.
I can calculate the position by a simple formula :
position = 16 * y + x
position = 16 * 2 + 2 // i put x = 2, y = 2 to formula
position = 34 // get number 34, that means i will start storing at 35th byte in this case it's d5
binaryFile . seekg ( position ) // jump to position in a file ( itc it's 99 )
binaryFile . read ( ( char * )&dest, z )) // save z bytes
If i put z = 3 i will store 3 bytes : d5, 3b, ac.
But somtimes coefficient z , x , y are not integers:
If i put y = 2, x = 1,5 and z = 3 // ( 1,5, 2 ) That means i have to jump at byte not 99 but d5 then store 2 bytes in this case d5 , 3b and add to them half byte from byte 99 and half byte from byte ac because the starting position was x = 1,5. How could I do that ??
You have to extend to byte boundaries on both ends, and first read the area that you want to write. So, if you want to write two bytes, you will have to read three bytes.
Then you will have to do appropriate bit shifting and masking to get your bits in the right places.
For example, if you are going to write two bytes shifted ½ byte, you would start with something like this:
unsigned char *mydata = MyDataToWrite();
unsigned char temp[bigEnough];
binaryFile.input(temp, 3);
temp[0] = (temp[0] & 0xf0) | (mydata[0] >> 4);
// more code here to put bits in temp
binaryFile.output(temp, 3);
Once you have your data in temp, write the 3 bytes back to the same location from which the were read.
I'm not going to write the whole thing here, but I hope this gives you an idea you can work from

Regular expression sequence matching

Is it possible to create a regular expression to find an incrementing sequence of hex numbers? I am trying to find number sequences (4 numbers long) inside seemingly random hex number strings.
... 59 fd 25 bf b1 b2 b3 b4 39 ca ...
... 35 c1 55 c4 c5 c6 c7 74 92 e1 ...
I was hoping to find the pattern b1 b2 b3 b4 in line 1 and c4 c5 c6 c7 in line 2.
Group matching will find same number sequences... /(\w\w)\1{3}/ will find c4 c4 c4 c4 but I haven't found a way to match the incrementing sequence.
Any ideas?
Regex is used for matching patterns occurring repeatedly not for matching patterns occurring incrementally
You better parse it with your own parser