main.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * Tema 2 ASC
  3. * 2020 Spring
  4. * !!! Do not modify this file !!!
  5. */
  6. #include "utils.h"
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include <sys/mman.h>
  14. #include <string.h>
  15. //used to generate random numbers between [-limit, limit]
  16. #define RANGE 1
  17. #define SAFE_ASSERT(condition, message) while(condition) { \
  18. perror(message); \
  19. goto failure; \
  20. }
  21. /*
  22. * Function which reads an input file in a specific format and fills
  23. * a vector of 'struct test's.
  24. */
  25. int read_input_file(char *input_file, int *num_tests, struct test **tests)
  26. {
  27. FILE *file = NULL;
  28. struct test *aux = NULL;
  29. int ret = 0, i = 0;
  30. file = fopen(input_file, "r");
  31. SAFE_ASSERT(file == 0, "Failed opening file");
  32. ret = fscanf(file, "%d\n", num_tests);
  33. SAFE_ASSERT(ret < 1, "Failed reading from file");
  34. *tests = malloc(*num_tests * sizeof **tests);
  35. SAFE_ASSERT(*tests == 0, "Failed malloc");
  36. aux = *tests;
  37. for (i = 0; i < *num_tests; i++) {
  38. struct test t;
  39. ret = fscanf(file, "%d %d %s\n", &t.N, &t.seed, t.output_save_file);
  40. SAFE_ASSERT(ret == 0, "Failed reading from file");
  41. *aux++ = t;
  42. }
  43. fclose(file);
  44. return 0;
  45. failure:
  46. if (aux) {
  47. free(aux);
  48. }
  49. if (file) {
  50. fclose(file);
  51. }
  52. return -1;
  53. }
  54. /*
  55. * Write a NxN complex number matrix to a binary file
  56. */
  57. int write_cmat_file(char *filepath, int N, double *data) {
  58. int ret, fd;
  59. size_t size;
  60. double *map = NULL;
  61. fd = open(filepath, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0777);
  62. SAFE_ASSERT(fd < 0, "Error opening file for writing");
  63. size = N * N * sizeof(double);
  64. ret = lseek(fd, size - 1, SEEK_SET);
  65. SAFE_ASSERT(ret < 0, "Error calling lseek() to stretch file");
  66. ret = write(fd, "", 1);
  67. SAFE_ASSERT(ret < 0, "Error writing in file");
  68. map = (double *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  69. SAFE_ASSERT(map == MAP_FAILED, "Error mapping the file");
  70. memcpy(map, data, size);
  71. ret = msync(map, size, MS_SYNC);
  72. SAFE_ASSERT(ret < 0, "Could not sync the file to disk");
  73. ret = munmap(map, size);
  74. SAFE_ASSERT(ret < 0, "Error unmapping the file");
  75. close(fd);
  76. return 0;
  77. failure:
  78. if (fd > 0) {
  79. close(fd);
  80. }
  81. return -1;
  82. }
  83. /*
  84. * Generate the test data, based on the number of elements and
  85. * the seed in the struct test. Allocates the arrays and fills
  86. * them with random numbers in [-RANGE, RANGE] (see RANGE define
  87. * above).
  88. */
  89. int generate_data(struct test t, double **A, int triangular)
  90. {
  91. int N = t.N, i, j;
  92. double *aux;
  93. *A = calloc(N * N, sizeof(double));
  94. SAFE_ASSERT(*A == 0, "Failed calloc");
  95. aux = *A;
  96. srand(t.seed);
  97. for (i = 0; i < N; ++i) {
  98. for ( j = (triangular ? i : 0); j < N; ++j) {
  99. aux[i * N + j] = get_rand_double(RANGE);
  100. }
  101. }
  102. return 0;
  103. failure:
  104. return -1;
  105. }
  106. /*
  107. * Generates data and runs the solver on the data.
  108. */
  109. int run_test(struct test t, Solver solve, float *elapsed)
  110. {
  111. double *A, *B, *res;
  112. int ret;
  113. struct timeval start, end;
  114. ret = generate_data(t, &A, 1);
  115. if (ret < 0)
  116. return ret;
  117. ret = generate_data(t, &B, 0);
  118. if (ret < 0)
  119. return ret;
  120. gettimeofday(&start, NULL);
  121. res = solve(t.N, A, B);
  122. gettimeofday(&end, NULL);
  123. if (res) {
  124. write_cmat_file(t.output_save_file, t.N, res);
  125. }
  126. *elapsed = ((end.tv_sec - start.tv_sec) * 1000000.0f + end.tv_usec - start.tv_usec) / 1000000.0f;
  127. if (A) {
  128. free(A);
  129. }
  130. if (B) {
  131. free(B);
  132. }
  133. if (res) {
  134. free(res);
  135. }
  136. return 0;
  137. }
  138. int main(int argc, char **argv) {
  139. int num_tests, ret, i;
  140. struct test *tests;
  141. float small_bonus_time = 8.00;
  142. float big_bonus_time = 4.00;
  143. int big_bonus = 0, small_bonus = 0;
  144. if (argc < 2) {
  145. printf("Please provide an input file: %s input_file\n", argv[0]);
  146. return -1;
  147. }
  148. ret = read_input_file(argv[1], &num_tests, &tests);
  149. if(ret < 0)
  150. return ret;
  151. for (i = 0; i < num_tests; i++) {
  152. float current_elapsed = 0.0f;
  153. ret = run_test(tests[i], my_solver, &current_elapsed);
  154. if (ret < 0){
  155. free(tests);
  156. return -1;
  157. }
  158. printf("Run=%s: N=%d: Time=%.6f\n", argv[0], tests[i].N, current_elapsed);
  159. if (!strcmp(argv[0], "./tema2_opt_m")) {
  160. if (i == 2) {
  161. if (current_elapsed <= big_bonus_time) {
  162. big_bonus = 1;
  163. }
  164. if (current_elapsed <= small_bonus_time) {
  165. small_bonus = 1;
  166. }
  167. }
  168. }
  169. }
  170. if (!strcmp(argv[0], "./tema2_opt_m")) {
  171. printf("<<< Bonus=%s >>>\n",
  172. (big_bonus ? "20p" :
  173. (small_bonus ? "10p" : "No"
  174. )
  175. )
  176. );
  177. }
  178. free(tests);
  179. return 0;
  180. }