UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
gpu.cu
Go to the documentation of this file.
1/*
2 * =====================================================================================
3 *
4 * Filename: hello.cu
5 *
6 * Description: CUDA test
7 *
8 * Version: 1.0
9 * Created: 02/06/2012 03:54:42 PM
10 * Revision: none
11 * Compiler: gcc
12 *
13 * Authors: Milan Kabat (kabat@ics.muni.cz), Vojtech David (374572@mail.muni.cz)
14 * Company: FI MUNI
15 *
16 * =====================================================================================
17 */
18
19#include <stdio.h>
20#include <signal.h>
21#include <emmintrin.h>
22#include <cuda.h>
23#include <cuda_runtime.h>
24//#include "timer-util.h"
25#include "gpu.cuh"
26
29 int k;
30 int m;
33};
34
35__global__ void frame_encode(char * data,int * pcm,struct coding_params * params);
36
37__global__ void frame_encode_int_big(int *data, int *pcm,int param_k,int param_m,int w_f,int packet_size);
38
39__global__ void frame_encode_staircase(int *data, int *pcm,int param_k,int param_m,int w_f,int packet_size);
40
41__global__ void frame_decode(char * received, int * pcm, int * error_vec,int * sync_vec,int packet_size,int max_row_weight,int K);
42
43__global__ void frame_encode_int(int *data, int *pcm,int param_k,int param_m,int w_f,int packet_size);
44
45__global__ void frame_decode_int(int * received, int * pcm, int * error_vec,int * sync_vec,int packet_size,int max_row_weight,int K);
46
47void gpu_encode ( char* source_data,int* pc_matrix, struct coding_params * );
48
49void gpu_decode (char * received,int * pcm,struct coding_params * params,int * error_vec,int * sync_vec,int undecoded,int * frame_size);
50
51__device__ unsigned int count = 0;
52__device__ unsigned int count_M = 0;
53char *xor_using_sse2 (char *source, char *dest, int packet_size)
54{
55 //First, do as many 128-bit XORs as possible
56 int iter_bytes_16 = 0;
57 int iter_bytes_4 = 0;
58 int iter_bytes_1 = 0;
59
60 iter_bytes_16 = (packet_size / 16) * 16;
61
62 if ( iter_bytes_16 > 0)
63 {
64
65 // printf ( "iter_bytes: %d\n", iter_bytes );
66 __m128i *wrd_ptr = (__m128i *) source;
67 __m128i *wrd_end = (__m128i *) (source + iter_bytes_16);
68 __m128i *dst_ptr = (__m128i *) dest;
69
70 // printf ( "wrd_ptr address: %p\n", wrd_ptr );
71 do
72 {
73 __m128i xmm1 = _mm_loadu_si128(wrd_ptr);
74 __m128i xmm2 = _mm_loadu_si128(dst_ptr);
75
76 xmm1 = _mm_xor_si128(xmm1, xmm2); // XOR 4 32-bit words
77 _mm_storeu_si128(dst_ptr, xmm1);
78 ++wrd_ptr;
79 ++dst_ptr;
80
81 }
82 while (wrd_ptr < wrd_end);
83 }
84 //Check, whether further XORing is necessary
85 if ( iter_bytes_16 < packet_size )
86 {
87 char *mark_source = source + iter_bytes_16;
88 char *mark_dest = dest + iter_bytes_16;
89
90 iter_bytes_4 = ((packet_size - iter_bytes_16) / 4) * 4;
91
92 for ( int i = 0; i < (packet_size - iter_bytes_16) / 4; i++)
93 {
94 int *s = ((int *) mark_source) + i;
95 int *d = ((int *) mark_dest) + i;
96 *d ^= *s;
97 }
98
99 mark_source += iter_bytes_4;
100 mark_dest += iter_bytes_4;
101
102 iter_bytes_1 = packet_size - iter_bytes_16 - iter_bytes_4;
103
104 for ( int i = 0; i < iter_bytes_1; i++)
105 {
106 *(mark_dest + i) ^= *(mark_source + i);
107 }
108 }
109
110 return dest;
111}
112
113void gpu_encode_upgrade (char * source_data,int *OUTBUF, int * PCM,int param_k,int param_m,int w_f,int packet_size ,int buf_size)
114{
115
116 // cudaError_t error;
117 int blocksize = packet_size/sizeof(int);
118 // printf("blocksize: %d\npacket size: %d\n",blocksize,packet_size );
119 if(blocksize>256){
120 if(blocksize>1024) blocksize=1024;
121 // puts("big one");
122 frame_encode_int_big <<< param_m, blocksize, packet_size >>> (OUTBUF,PCM, param_k, param_m, w_f, packet_size);
123 cuda_check_error("frame_encode_int_big");
124
125 frame_encode_staircase<<< 1, blocksize, packet_size >>> (OUTBUF, PCM, param_k, param_m, w_f, packet_size);
126 cuda_check_error("frame_encode_staircase");
127
128 cudaMemcpy(source_data + param_k*packet_size,OUTBUF + (param_k*packet_size)/4, param_m*packet_size,cudaMemcpyDeviceToHost );
129 // // cudaMemcpy(source_data,OUTBUF, buf_size,cudaMemcpyDeviceToHost );
130 cuda_check_error("memcpy out_buf");
131
132
133 // gettimeofday(&t0, 0);
134 // for ( int m = 1; m < param_m; ++m)
135 // {
136 // char *prev_parity = (char *) source_data + (param_k + m - 1) * packet_size;
137 // char *parity_packet = (char *) source_data + (param_k + m) * packet_size;
138 // xor_using_sse2(prev_parity, parity_packet, packet_size);
139
140 // }
141 // gettimeofday(&t1, 0);
142 // long elapsed = (t1.tv_sec - t0.tv_sec) * 1000000 + t1.tv_usec - t0.tv_usec;
143 // printf("time staircase: %f\n",elapsed/1000.0 );
144
145 }
146 else{
147 // puts("chudy soused");
148 frame_encode_int <<< param_m, blocksize, packet_size >>> (OUTBUF,PCM, param_k, param_m, w_f, packet_size);
149 cuda_check_error("frame_encode_int");
150
151 cudaMemcpy(source_data + param_k*packet_size,OUTBUF + (param_k*packet_size)/4, param_m*packet_size,cudaMemcpyDeviceToHost );
152 // cudaMemcpy(source_data,OUTBUF, buf_size,cudaMemcpyDeviceToHost );
153 cuda_check_error("memcpyu out_buf");
154
155 for ( int m = 1; m < param_m; ++m)
156 {
157 char *prev_parity = (char *) source_data + (param_k + m - 1) * packet_size;
158 char *parity_packet = (char *) source_data + (param_k + m) * packet_size;
159 xor_using_sse2(prev_parity, parity_packet, packet_size);
160
161 }
162
163 }
164
165
166
167 // cudaEvent_t start, stop;
168 // float time;
169 // cudaEventCreate(&start);
170 // cudaEventCreate(&stop);
171
172 // cudaEventRecord(start, 0);
173
174 // cudaStream_t pStream;
175 // cudaStreamCreate(&pStream);
176 // frame_encode_staircase<<< 1, blocksize, packet_size >>> (OUTBUF, PCM, param_k, param_m, w_f, packet_size);
177 // cuda_check_error("frame_encode_staircase");
178
179
180
181 // cudaStreamSynchronize();
182 // cudaDeviceSynchronize();
183
184 return;
185}
186
187#define CHECK_CUDA(cmd) do { \
188 cudaError_t err = cmd; \
189 if (err != cudaSuccess) {\
190 fprintf(stderr, "[LDGM GPU] %s: %s\n", #cmd, cudaGetErrorString(err)); \
191 } \
192} while(0)
193
194void gpu_decode_upgrade(char *data, int * PCM,int* SYNC_VEC,int* ERROR_VEC, int not_done, int *frame_size,int * error_vec,int * sync_vec,int M,int K,int w_f,int buf_size,int packet_size)
195{
196
197
198 cudaError_t error;
199 int *received_d;
200
201
202 // int M = params->m;
203 // int K = params->k;
204 // int w_f = params->max_row_weight + 2;
205 // int buf_size = params->buf_size;
206
207 int* received = (int*) data;
208 // printf("K: %d, M: %d, max_row_weight: %d, buf_size: %d,\n packet_size: %d\n",K,M,w_f,buf_size,packet_size );
209 // printf("NOT DONE: %d\n",not_done );
210
211
212 error = cudaHostRegister(received, buf_size, cudaHostRegisterMapped);
213 if (error != cudaSuccess) printf("1 %s\n", cudaGetErrorString(error));
214
215 error = cudaHostGetDevicePointer((void **) & (received_d), (void *)received, 0);
216 if (error != cudaSuccess) printf("2 %s\n", cudaGetErrorString(error));
217
218 // error = cudaMalloc(&received_d, buf_size);
219 // if (error != cudaSuccess) printf("1 %s\n", cudaGetErrorString(error));
220
221 // error = cudaMemcpy(received_d, received, buf_size, cudaMemcpyHostToDevice);
222 // if (error != cudaSuccess) printf("2 %s\n", cudaGetErrorString(error));
223
224 // error = cudaMalloc(&pcm_d, w_f * M * sizeof(int));
225 // if (error != cudaSuccess) printf("3 %s\n", cudaGetErrorString(error));
226
227 // error = cudaMemcpy(pcm_d, PCM, w_f * M * sizeof(int), cudaMemcpyHostToDevice);
228 // if (error != cudaSuccess) printf("4 %s\n", cudaGetErrorString(error));
229
230
231 // error = cudaMalloc(&error_vec_d, (K + M) * sizeof(int));
232 // if (error != cudaSuccess)printf("5 %s\n", cudaGetErrorString(error));
233
234 // error = cudaMemcpy(error_vec_d, error_vec, (K + M) * sizeof(int), cudaMemcpyHostToDevice);
235 // if (error != cudaSuccess) printf("6 %s\n", cudaGetErrorString(error));
236
237 // error = cudaMalloc(&sync_vec_d, (K + M) * sizeof(int));
238 // if (error != cudaSuccess) printf("7 %s\n", cudaGetErrorString(error));
239
240 // error = cudaMemcpy(sync_vec_d, sync_vec, (K + M) * sizeof(int), cudaMemcpyHostToDevice);
241 // if (error != cudaSuccess) printf("8 %s\n", cudaGetErrorString(error));
242
243 int ps = packet_size/sizeof(int);
244
245 int blocksize = packet_size/sizeof(int) +1;
246 // printf("blocksize: %d\npacket size: %d\n",blocksize,packet_size );
247 if(blocksize>512) blocksize=512;
248
249 int not_done_source=0;
250 for (int i = 0; i < K; i++)
251 {
252 if (error_vec[i] == 1) not_done_source++;
253 }
254 // printf("not_done %d\n",not_done );
255 // printf("not_done_source %d\n",not_done_source);
256
257
258 unsigned int count_host = 0;
259 unsigned int count_host_M = 0;
260
261 CHECK_CUDA(cudaMemcpyToSymbol ( count, (void *)(&count_host), sizeof(unsigned int), 0, cudaMemcpyHostToDevice));
262 CHECK_CUDA(cudaMemcpyToSymbol ( count_M, (void *)(&count_host_M), sizeof(unsigned int), 0, cudaMemcpyHostToDevice));
263
264
265 int i = 0;
266 for (i = 1; i < 30; ++i)
267 {
268 //__global__ void frame_decode_int(int * received, int * pcm, int * error_vec,int * sync_vec,int packet_size,int max_row_weight,int K);
269 frame_decode_int <<< M, blocksize , packet_size >>> (received_d, PCM, ERROR_VEC, SYNC_VEC, ps, w_f-2, K);
270 error = cudaGetLastError();
271 if (error != cudaSuccess) printf("3 %s\n", cudaGetErrorString(error));
272
273 // cudaDeviceSynchronize();
274 //error = cudaMemcpyFromSymbol((void *)(&count_host), count, sizeof(int), 0, cudaMemcpyDeviceToHost);
275 count_host=0;
276 error = cudaMemcpyFromSymbol((void*)(&count_host), count, sizeof(unsigned int), 0, cudaMemcpyDeviceToHost);
277 if (error != cudaSuccess) printf("10 %s\n", cudaGetErrorString(error));
278 // printf("count host %d\n",count_host );
279
280 if (count_host == not_done_source)
281 {
282 break;
283 }
284
285
286 CHECK_CUDA(cudaMemcpyFromSymbol((void*)(&count_host_M), count_M, sizeof(unsigned int), 0, cudaMemcpyDeviceToHost));
287 // printf("count host_M %d\n",count_host_M );
288 if (count_host_M == M)
289 {
290 break;
291 }
292
293 count_host_M = 0;
294 CHECK_CUDA(cudaMemcpyToSymbol ( count_M, (void *)(&count_host_M), sizeof(unsigned int), 0, cudaMemcpyHostToDevice));
295
296
297 }
298 // printf("iterace: %d\n",i);
299
300
301 // cudaDeviceSynchronize();
302 //cudaThreadSynchronize();
303
304 CHECK_CUDA(cudaMemcpy(error_vec, ERROR_VEC, (K + M) * sizeof(int), cudaMemcpyDeviceToHost));
305
306
307 int a = 0;
308 int fs = 0;
309 for (int i = 0; i < K; i++)
310 {
311 if (error_vec[i] == 1) a++;
312 }
313
314 // printf("UNDECODED: %d NOT DONE: %d DEKODOVANO: %d\n",a,not_done,not_done-a);
315 if (a != 0)
316 {
317 *frame_size = 0;
318
319 }
320 else
321 {
322 memcpy(&fs, received, 4);
323 // printf("received size %d\n",fs );
324 *frame_size = fs;
325 }
326 // printf("undecoded: %d, frame_size: %d, undecoded subtract: %d\n",a,fs,not_done-a );
327
328 CHECK_CUDA(cudaHostUnregister(received));
329 // cudaFree(received_d);
330 // cudaFree(pcm_d);
331 // cudaFree(error_vec_d);
332 // cudaFree(sync_vec_d);
333 // cudaFree(params_d);
334
335
336 // puts("END");
337 return;
338
339}
340__global__ void frame_encode_int_big(int *data, int *pcm,int param_k,int param_m,int w_f,int packet_size)
341{
342 int ps = packet_size/sizeof(int);
343
344 int bx = blockIdx.x;
345 int x = threadIdx.x;
346 int offset;
347
348
349 // printf("K: %d M: %d max_row_weight: %d packet_size: %d\n",param_k,param_m,max_row_weight,ps);
350 extern __shared__ int parity_packet[];
351 // int *parity_packet = data + (param_k + bx) * ps;
352
353 // if(x==0)printf("bx %d has parity packet at: %d,%d\n",bx,param_k*ps + bx*ps,param_k+bx );
354
355
356 offset = x;
357 while (offset < ps)
358 {
359 parity_packet[offset]=0;
360 offset += blockDim.x;
361 }
362 // __syncthreads();
363
364 for ( int i = 0; i < w_f; i++)
365 {
366 int idx = pcm[bx * w_f + i];
367 //printf ( "adept: %d\n", idx );
368
369 // if(x==0) printf ("block %d xor packet: %d\n",bx,idx);
370 if (idx > -1 && idx < param_k)
371 {
372
373 //xoring parity_packet ^ idx
374 offset = x;
375 while (offset < ps)
376 {
377 parity_packet[offset]^=data[idx*ps + offset];
378 offset += blockDim.x;
379 }
380
381 }
382 }
383 // __syncthreads();
384 offset = x;
385 while (offset < ps)
386 {
387 data[(param_k + bx) * ps + offset]= parity_packet[offset];
388 offset += blockDim.x;
389 }
390
391
392}
393
394__global__ void frame_encode_int(int *data, int *pcm,int param_k,int param_m,int w_f,int packet_size)
395{
396 int ps = packet_size/sizeof(int);
397
398 int bx = blockIdx.x;
399 int offset = threadIdx.x;
400
401
402
403 // printf("K: %d M: %d max_row_weight: %d packet_size: %d\n",param_k,param_m,max_row_weight,ps);
404 extern __shared__ int parity_packet[];
405 // int *parity_packet = data + (param_k + bx) * ps;
406
407 // if(x==0)printf("bx %d has parity packet at: %d,%d\n",bx,param_k*ps + bx*ps,param_k+bx );
408
409
410 // while (offset < ps)
411 // {
412 // parity_packet[offset]=0;
413 // offset += blockDim.x;
414 // }
415 parity_packet[offset]=0;
416 // __syncthreads();
417
418 for ( int i = 0; i < w_f; i++)
419 {
420 int idx = pcm[bx * w_f + i];
421 //printf ( "adept: %d\n", idx );
422
423 // if(x==0) printf ("block %d xor packet: %d\n",bx,idx);
424 if (idx > -1 && idx < param_k)
425 {
426
427 //xoring parity_packet ^ idx
428 // offset = x;
429 // while (offset < ps)
430 // {
431 // parity_packet[offset]^=data[idx*ps + offset];
432 // offset += blockDim.x;
433 // }
434 parity_packet[offset]^=data[idx*ps + offset];
435
436 }
437 }
438 // __syncthreads();
439 // offset = x;
440 // while (offset < ps)
441 // {
442 // data[(param_k + bx) * ps + offset]= parity_packet[offset];
443 // offset += blockDim.x;
444 // }
445
446 data[(param_k + bx) * ps + offset]= parity_packet[offset];
447 // __syncthreads();
448
449}
450
451
452__global__ void frame_decode_int(int *received, int *pcm, int *error_vec, int *sync_vec, int packet_size, int max_row_weight, int K)
453{
454 //TITAN
455
456 __shared__ int undecoded;
457 __shared__ int undecoded_index;
458 __shared__ int ret;
459
460
461 extern __shared__ int shared_parity_packet[];
462 int w_f = max_row_weight + 2;
463 int ps = packet_size;
464
465 int bx = blockIdx.x;
466 int x = threadIdx.x;
467
468 int offset = 0;
469
470 if (x == 0)
471 {
472 ret = 0;
473 undecoded = 0;
474 undecoded_index = -1;
475 for (int j = 0; j < w_f; j++)
476 {
477 int p = pcm[bx * w_f + j];
478 //printf("%d %d %d\n",p, error_vec[p],x);
479 if (p != -1 && error_vec[p] == 1)
480 {
481 undecoded++;
482 undecoded_index = p;
483 }
484 }
485 if (undecoded == 1)
486 {
487 ret = atomicCAS(sync_vec + undecoded_index, 1, 0);
488 }
489
490 }
491 __syncthreads();
492 if (ret == 1)
493 {
494
495 // if(x==0) printf("decoding %7d, bx %7d\n",undecoded_index,bx );
496 offset = x;
497
498 while (offset < ps)
499 {
500 shared_parity_packet[offset]=0x0;
501 offset += blockDim.x;
502 }
503 /*int zbyva = ps - offset;
504 if (x < zbyva)
505 {
506 shared_parity_packet[x + offset] = 0;
507 }*/
508
509 __syncthreads();
510 // if(x==0) printf("decoding [%d]\n",undecoded_index);
511 for (int j = 0; j < w_f; j++)
512 {
513 int index = pcm[bx * w_f + j];
514 if (index != undecoded_index && index != -1)
515 {
516 offset = x;
517 while ( offset < ps)
518 {
519 shared_parity_packet[offset] ^= received[index*ps + offset];
520 offset += blockDim.x;
521 }/*
522 int zbyva = ps - offset;
523 if (x < zbyva)
524 {
525 shared_parity_packet[x + offset] ^= received[(index * ps) + x + offset];
526 }*/
527
528
529 }
530
531 }
532 __syncthreads();
533 offset = x;
534
535 while ( offset < ps)
536 {
537 // *((int *)(received + (undecoded_index * ps) + 4*x + a)) = *((int *)(shared_parity_packet + a + 4 * x));
538 received[(undecoded_index * ps) + offset] = shared_parity_packet[offset];
539 offset += blockDim.x;
540 }
541/*
542 zbyva = ps - offset;
543 if (x < zbyva)
544 {
545 received[(undecoded_index * ps) + x + offset] = shared_parity_packet[x + offset];
546 }*/
547
548
549 }
550 if (x == 0 && ret == 1)
551 {
552 //error_vec[undecoded_index]=0;
553 atomicCAS(error_vec + undecoded_index, 1, 0);
554 // printf("node %d %d done\n",undecoded_index);
555 }
556 if (x == 0 && ret==1 && undecoded_index<K)
557 {
558 atomicAdd(&count, 1);
559 }
560 if (x == 0 && undecoded!=1 )
561 {
562 atomicAdd(&count_M, 1);
563 }
564
565
566
567
568}
569
570
571__global__ void frame_encode_staircase(int *data, int *pcm,int param_k,int param_m,int w_f,int packet_size)
572{
573 int ps = packet_size/sizeof(int);
574
575 int x = threadIdx.x;
576
577 for (int index = param_k; index < param_k + param_m-1; index++)
578 {
579
580 int offset = x;
581
582 while (offset < ps)
583 {
584 // *((int *)(data + (index+1)*ps + offset + intSize * x)) ^= *((int *)(data + index * ps + intSize * x + offset));
585 data[(index+1)*ps + offset] ^= data[index*ps + offset];
586 offset += blockDim.x;
587 }
588
589
590
591 }
592
593
594}
static __device__ const float offset
Definition cuda_dxt.cu:139
#define cudaMemcpy
#define cudaSuccess
#define cudaMemcpyHostToDevice
#define cudaGetLastError
#define cudaError_t
#define cudaGetErrorString
__global__ void frame_decode(char *received, int *pcm, int *error_vec, int *sync_vec, int packet_size, int max_row_weight, int K)
__device__ unsigned int count
Definition gpu.cu:51
void gpu_encode(char *source_data, int *pc_matrix, struct coding_params *)
__global__ void frame_encode_int(int *data, int *pcm, int param_k, int param_m, int w_f, int packet_size)
Definition gpu.cu:394
__global__ void frame_encode(char *data, int *pcm, struct coding_params *params)
void gpu_decode(char *received, int *pcm, struct coding_params *params, int *error_vec, int *sync_vec, int undecoded, int *frame_size)
void gpu_encode_upgrade(char *source_data, int *OUTBUF, int *PCM, int param_k, int param_m, int w_f, int packet_size, int buf_size)
Definition gpu.cu:113
char * xor_using_sse2(char *source, char *dest, int packet_size)
Definition gpu.cu:53
#define CHECK_CUDA(cmd)
Definition gpu.cu:187
__device__ unsigned int count_M
Definition gpu.cu:52
__global__ void frame_encode_staircase(int *data, int *pcm, int param_k, int param_m, int w_f, int packet_size)
Definition gpu.cu:571
__global__ void frame_encode_int_big(int *data, int *pcm, int param_k, int param_m, int w_f, int packet_size)
Definition gpu.cu:340
void gpu_decode_upgrade(char *data, int *PCM, int *SYNC_VEC, int *ERROR_VEC, int not_done, int *frame_size, int *error_vec, int *sync_vec, int M, int K, int w_f, int buf_size, int packet_size)
Definition gpu.cu:194
__global__ void frame_decode_int(int *received, int *pcm, int *error_vec, int *sync_vec, int packet_size, int max_row_weight, int K)
Definition gpu.cu:452
Definition rtp.c:206
int num_lost
Definition gpu.cu:28
int packet_size
Definition gpu.cu:31
int max_row_weight
Definition gpu.cu:32