lab2-stephen-stengel.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #ifndef STEPHEN_STENGEL_LAB2lol
  2. #define STEPHEN_STENGEL_LAB2lol
  3. #include <stdio.h>
  4. #include <omp.h>
  5. #include "mylab1functions.h"
  6. #define MAX_FILENAME_LEN 500
  7. #define MAX_STR_LEN 50
  8. //function definitions
  9. void testStringPass(char * dataStr);
  10. void writeDataToFile(char * filename, int m, int n, int t, double time, char * testType);
  11. void doAlmostNothing();
  12. int runFuncTest(double **myFunc(), char * dataFile, char * picsFile, int maxM, int N, int maxT, char * testType);
  13. void timeThisWay(double **myFunc(), double **myArray, char *dataFile, char *picsFile, int m, int N, int tee, char *testType);
  14. double powerArraysThisWay(double **myFunc(), double **myArray, int m, int N, int tee);
  15. //functions
  16. //Appends a (m n t time) datapoint to the end of the given filename.
  17. void writeDataToFile(char * filename, int m, int n, int t, double time, char * testType)
  18. {
  19. FILE *myFile = fopen(filename, "a");
  20. fprintf(myFile, "%d %d %d %f %s\n", m, n, t, time, testType);
  21. fclose(myFile);
  22. }
  23. //This tests the time of the given function. col, row, or individual. maybe block if I have time.
  24. //The given function will handle printing? This function will handle the parameters going to the
  25. //test function.
  26. int runFuncTest(double **myFunc(), char * dataFile, char * picsFile, int maxM, int N, int maxT, char * testType)
  27. {
  28. double start = omp_get_wtime();
  29. int numThreadTests = 10;
  30. int tIncrement = 1;
  31. if ((maxT / numThreadTests) > 1)
  32. {
  33. tIncrement = (maxT / numThreadTests);
  34. }
  35. printf("tIncrement: %d\n", tIncrement);
  36. int mStep = 1;
  37. if ( maxM > 100 )
  38. {
  39. mStep = maxM / 20; //20 chosen because it is a good balance.
  40. }
  41. int tTop = maxT - (maxT - (tIncrement * (numThreadTests - 1))) + 1;
  42. printf("tTop: %d\n", tTop);
  43. for (int tee = tTop; tee > 0; tee -= tIncrement)//backwards keeps openMP from killing useful threads
  44. {
  45. printf("This T: %d\n", tee);
  46. for (int m = 1; m < maxM + 1; m += mStep)
  47. {
  48. double **myArray = createSquareArray(m);
  49. myArray = fillSquareArrayRandomDoubles(myArray, m);
  50. //This function will find the min of three times for these inputs and write data to file.
  51. timeThisWay(myFunc, myArray, dataFile, picsFile, m, N, tee, testType);
  52. freeSquareDoubleArray(myArray, m);
  53. }
  54. }//end of loop that varies num threads
  55. double elapsedTime = omp_get_wtime() - start;
  56. printf("runfunctest: %s complete in %.2fs! now printing to file...\n", testType, elapsedTime);
  57. //make graph
  58. char printCommandCell[MAX_COMMAND_LEN];
  59. sprintf(printCommandCell, "python3 cArrayGraph.py %s %s %s", dataFile, picsFile, testType);
  60. system( printCommandCell );
  61. printf("done!\n");
  62. return 0;
  63. }
  64. //gets the time of doin it this way
  65. void timeThisWay(double **myFunc(), double **myArray, char *dataFile, char *picsFile, int m, int N, int tee, char *testType)
  66. {
  67. double lowest = INT_MAX;
  68. double elapsedTime = -1;
  69. //do three tests timing each
  70. for (int k = 0; k < 3; k++)
  71. {
  72. elapsedTime = powerArraysThisWay(myFunc, myArray, m, N, tee);
  73. if (elapsedTime < lowest)
  74. {
  75. lowest = elapsedTime;
  76. }
  77. }
  78. //~ //append the i, j, time to a file
  79. writeDataToFile(dataFile, m, N, tee, lowest, testType);
  80. }
  81. //calls the specific multiplication func needed and returns runtime minus thread creation (should be zero because openmp keeps threads sleeping)
  82. double powerArraysThisWay(double **myFunc(), double **myArray, int m, int N, int tee)
  83. {
  84. //~ double **originalCopy = copySquareDoubleArray(myArray, m);
  85. double **originalCopy = myArray;
  86. double **intermediate = copySquareDoubleArray(myArray, m);
  87. //create timing vars here
  88. struct timespec start, finish;
  89. double elapsedTime = -1;
  90. clock_gettime(CLOCK_MONOTONIC, &start);
  91. //~ double ompTimeStart = omp_get_wtime();
  92. for (int i = 1; i < N; i++)
  93. {
  94. double **output = createSquareArray(m);
  95. output = myFunc(originalCopy, intermediate, output, m, tee);
  96. //copy output into intermediate
  97. intermediate = copySquareDoubleArray(output, m);
  98. freeSquareDoubleArray(output, m);
  99. }
  100. elapsedTime = getElapsedTime(start, finish);
  101. //~ double ompTimeElapsed = omp_get_wtime() - ompTimeStart;
  102. //~ if ( abs(ompTimeElapsed - elapsedTime) > 0 )
  103. //~ {
  104. //~ printf("time.h time: %f\tomp_get_wtime(): %f\n", elapsedTime, ompTimeElapsed);
  105. //~ }
  106. freeSquareDoubleArray(intermediate, m);
  107. //~ freeSquareDoubleArray(originalCopy, m);
  108. return elapsedTime;
  109. }
  110. double **multSquareArraysThreadCell(double **original, double **intermediate, double **output, int size, int tee)
  111. {
  112. #pragma omp parallel num_threads(tee) //only use this many threads out of the threadpool
  113. {
  114. register int i = 0;
  115. register int j = 0;
  116. register int k = 0;
  117. //~ printf("current T: %d\tnumThreads: %d\n", tee, omp_get_num_threads());
  118. #pragma omp for collapse(2) nowait //each thread loops through the k's for each cell
  119. for (i = 0; i < size; i++)
  120. {
  121. for (j = 0; j < size; j++)
  122. {
  123. register double tmp = output[i][j];
  124. for (k = 0; k < size; k++)
  125. {
  126. tmp += original[i][k] * intermediate[k][j];
  127. }
  128. output[i][j] = tmp;
  129. }
  130. }
  131. }
  132. return output;
  133. }
  134. double **multSquareArraysThreadRow(double **original, double **intermediate, double **output, int size, int tee)
  135. {
  136. #pragma omp parallel num_threads(tee) //only use this many threads out of the threadpool
  137. {
  138. register int i = 0;
  139. register int j = 0;
  140. register int k = 0;
  141. #pragma omp for nowait //each thread has its own row i.
  142. for (i = 0; i < size; i++)
  143. {
  144. for (j = 0; j < size; j++)
  145. {
  146. register double tmp = output[i][j];
  147. for (k = 0; k < size; k++)
  148. {
  149. tmp += original[i][k] * intermediate[k][j];
  150. }
  151. output[i][j] = tmp;
  152. }
  153. }
  154. }
  155. return output;
  156. }
  157. //Same as row but with the i and j loops switched.
  158. double **multSquareArraysThreadCol(double **original, double **intermediate, double **output, int size, int tee)
  159. {
  160. #pragma omp parallel num_threads(tee) //only use this many threads out of the threadpool
  161. {
  162. register int i = 0;
  163. register int j = 0;
  164. register int k = 0;
  165. #pragma omp for nowait //each thread has its own col j.
  166. for (j = 0; j < size; j++)
  167. {
  168. for (i = 0; i < size; i++)
  169. {
  170. register double tmp = output[i][j];
  171. for (k = 0; k < size; k++)
  172. {
  173. tmp += original[i][k] * intermediate[k][j];
  174. }
  175. output[i][j] = tmp;
  176. }
  177. }
  178. }
  179. return output;
  180. }
  181. //Do almost nothing, used to make sure threads are created at start and not as needed.
  182. void doAlmostNothing()
  183. {
  184. int a = 0;
  185. int b = 0;
  186. a += b;
  187. }
  188. #endif
  189. //Unused
  190. /*
  191. //this tests times for running each separate thread size
  192. int runThreadTest(char * dataFile, char * picsFile, int maxM, int N, int maxT, char * testType)
  193. {
  194. //~ printf("enter any number to continue...\n");
  195. //~ int a;
  196. //~ scanf("%d", &a);
  197. //~ printf("num threads in pool: %d\n", omp_get_num_threads());
  198. //create timer variables.
  199. struct timespec start, finish;
  200. double lowest = INT_MAX;
  201. double elapsedTime = -1;
  202. int tIncrement = 1;
  203. if ((maxT / 10) > 1)
  204. {
  205. tIncrement = maxT / 10;
  206. }
  207. printf("tIncrement: %d\n", tIncrement);
  208. for (int tee = 1; tee <= maxT; tee += tIncrement)
  209. {
  210. //~ #pragma omp parallel num_threads(tee)
  211. {
  212. //~ #pragma omp single nowait
  213. printf("num threads in use: %d\n", omp_get_num_threads());
  214. //~ #pragma omp for private(start, finish, lowest, elapsedTime) nowait
  215. for (int i = 1; i < maxM + 1; i++)
  216. {
  217. //create array
  218. int sizeThisRound = i;
  219. //~ int teeThisRound = j;
  220. double **myArray = createSquareArray(sizeThisRound);
  221. myArray = fillSquareArrayRandomDoubles(myArray, sizeThisRound);
  222. //do three tests timing each
  223. lowest = INT_MAX;
  224. for (int k = 0; k < 3; k++)
  225. {
  226. clock_gettime(CLOCK_MONOTONIC, &start);
  227. powerArrays(myArray, sizeThisRound, N);
  228. elapsedTime = getElapsedTime(start, finish);
  229. if (elapsedTime < lowest)
  230. {
  231. lowest = elapsedTime;
  232. }
  233. }
  234. //~ //append the i, j, time to a file
  235. //~ #pragma omp critical
  236. {
  237. //~ writeDataToFile(dataFile, sizeThisRound, N, omp_get_num_threads(), lowest, testType);
  238. writeDataToFile(dataFile, sizeThisRound, N, tee, lowest, testType);
  239. }
  240. freeSquareDoubleArray(myArray, sizeThisRound);
  241. }
  242. }//end of parallel section.
  243. }//end of loop that varies num threads
  244. printf("runthreadtest complete!\n");
  245. return 0;
  246. }
  247. */