Advertisement
Guest User

Untitled

a guest
Oct 18th, 2017
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.37 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/mman.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <sys/wait.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <math.h>
  10. #include <string.h>
  11.  
  12. #include "float_vec.h"
  13. #include "barrier.h"
  14. #include "utils.h"
  15.  
  16.  
  17. // stackoverflow assisted with pointer arithmetic.
  18. // I knew I had to subtract a from b, but didn't know that
  19. // I had to cast to int* from void*
  20. int
  21. compare_function(const void* a, const void* b)
  22. {
  23.     return (*(int*)a - *(int*)b);
  24. }
  25.  
  26. void
  27. qsort_floats(floats* xs)
  28. {
  29.     // TODO: call qsort to sort the array
  30.     // see "man 3 qsort" for details
  31.     qsort(xs->data, xs->size, sizeof(float), compare_function);
  32. }
  33.  
  34. floats*
  35. sample(float* data, long size, int P)
  36. {
  37.     // TODO: sample the input data, per the algorithm decription
  38.     int array_size = 3 * (P - 1);
  39.     float sorted_array[array_size];
  40.     (void) sorted_array; // suppress unused warning
  41.  
  42.     floats* samps = make_floats(0);
  43.     floats_push(samps, 0);
  44.  
  45.     for (int i = 0; i < P - 1; i++) {
  46.         floats* temp = make_floats(0);
  47.         for (int j = 0; j < 3; j++) {
  48.             floats_push(temp, data[random() % size]);
  49.         }
  50.         qsort (temp->data, 3, sizeof(float), compare_function);
  51.         floats_push(samps, temp->data[1]);
  52.     }
  53.  
  54.     floats_push(samps, INFINITY);
  55.  
  56.     qsort(samps->data, P + 1, sizeof(float), compare_function);
  57.  
  58.  
  59.     return samps;
  60. }
  61.  
  62. void
  63. sort_worker(int pnum, float* data, long size, int P, floats* samps, long* sizes, barrier* bb)
  64. {
  65.     floats* xs = make_floats(0);
  66.     // TODO: select the floats to be sorted by this worker
  67.     float low = samps->data[pnum];
  68.     float high = samps->data[pnum + 1];
  69.  
  70.     for (int i = 0; i < size; i++) {
  71.         if (data[i] >= low && data[i] < high) {
  72.             floats_push(xs, data[i]);
  73.         }
  74.     }
  75.  
  76.     sizes[pnum] = xs->size;
  77.  
  78.     printf("%d: start %.04f, count %ld\n", pnum, samps->data[pnum], xs->size);
  79.  
  80.     // TODO: some other stuff
  81.  
  82.     qsort_floats(xs);
  83.  
  84.     // TODO: probably more stuff
  85.     barrier_wait(bb);
  86.  
  87.     int start = 0;
  88.     int end = 0;
  89.  
  90.     for (int i = 0; i < pnum; i++) {
  91.         start += sizes[i];
  92.         end += sizes[i];
  93.     }
  94.     end += sizes[pnum];
  95.     int index = 0;
  96.     for (int i = start; i < end; i++) {
  97.         data[i] = xs->data[index];
  98.         index++;
  99.     }
  100.  
  101.     free_floats(xs);
  102. }
  103.  
  104. void
  105. run_sort_workers(float* data, long size, int P, floats* samps, long* sizes, barrier* bb)
  106. {
  107.     pid_t kids[P];
  108.     (void) kids; // suppress unused warning
  109.  
  110.     // TODO: spawn P processes, each running sort_worker
  111.  
  112.     for (int i = 0; i < P; i++) {
  113.         // parent process
  114.         if ((kids[i] = fork())) {
  115.         }
  116.         else {
  117.             // child process
  118.             sort_worker(i, data, size, P, samps, sizes, bb);
  119.             exit(0);
  120.         }
  121.     }
  122.     for (int i = 0; i < P; i++) {
  123.         int rv = waitpid(kids[i], 0, 0);
  124.         check_rv(rv);
  125.     }
  126. }
  127.  
  128. void
  129. sample_sort(float* data, long size, int P, long* sizes, barrier* bb)
  130. {
  131.     floats* samps = sample(data, size, P);
  132.     run_sort_workers(data, size, P, samps, sizes, bb);
  133.     free_floats(samps);
  134. }
  135.  
  136. int
  137. main(int argc, char* argv[])
  138. {
  139.     if (argc != 3) {
  140.         printf("Usage:\n");
  141.         printf("\t%s P data.dat\n", argv[0]);
  142.         return 1;
  143.     }
  144.  
  145.     const int P = atoi(argv[1]);
  146.     const char* fname = argv[2];
  147.  
  148.     seed_rng();
  149.  
  150.     int rv;
  151.     struct stat st;
  152.     rv = stat(fname, &st);
  153.     check_rv(rv);
  154.  
  155.     const int fsize = st.st_size;
  156.     if (fsize < 8) {
  157.         printf("File too small.\n");
  158.         return 1;
  159.     }
  160.  
  161.     int fd = open(fname, O_RDWR);
  162.     check_rv(fd);
  163.  
  164.     void* file = mmap(NULL, fsize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); // TODO: load the file with mmap.
  165.     (void) file; // suppress unused warning.
  166.  
  167.     // TODO: These should probably be from the input file.
  168.     long count;
  169.     memcpy(&count, file, sizeof(long));
  170.     float* data = file + sizeof(long);
  171.  
  172.     long sizes_bytes = P * sizeof(long);
  173.     long* sizes = mmap(0, sizes_bytes, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); // TODO: This should be shared
  174.  
  175.     barrier* bb = make_barrier(P);
  176.  
  177.     sample_sort(data, count, P, sizes, bb);
  178.  
  179.     free_barrier(bb);
  180.  
  181.     // TODO: munmap your mmaps
  182.     check_rv(munmap(file, fsize));
  183.     check_rv(munmap(sizes, sizes_bytes));
  184.  
  185.     return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement