You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

353 lines
12 KiB

  1. #include "gtest/gtest.h"
  2. #include "src/storage/SparseMatrix.h"
  3. #include "src/exceptions/InvalidStateException.h"
  4. #include "src/exceptions/OutOfRangeException.h"
  5. #include "storm-config.h"
  6. #ifdef STORM_HAVE_CUDAFORSTORM
  7. #include "cudaForStorm.h"
  8. TEST(CudaPlugin, SpMV_4x4) {
  9. storm::storage::SparseMatrixBuilder<double> matrixBuilder(4, 4, 10);
  10. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  11. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 3, -1.0));
  12. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 8.0));
  13. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 7.0));
  14. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 2, -5.0));
  15. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 2.0));
  16. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 2.0));
  17. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 1, 2.0));
  18. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 2, 4.0));
  19. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 3, 4.0));
  20. storm::storage::SparseMatrix<double> matrix;
  21. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  22. ASSERT_EQ(4, matrix.getRowCount());
  23. ASSERT_EQ(4, matrix.getColumnCount());
  24. ASSERT_EQ(10, matrix.getEntryCount());
  25. std::vector<double> x({0, 4, 1, 1});
  26. std::vector<double> b({0, 0, 0, 0});
  27. ASSERT_NO_THROW(basicValueIteration_spmv_uint64_double(matrix.getColumnCount(), matrix.__internal_getRowIndications(), matrix.__internal_getColumnsAndValues(), x, b));
  28. ASSERT_EQ(b.at(0), 3);
  29. ASSERT_EQ(b.at(1), 25);
  30. ASSERT_EQ(b.at(2), 16);
  31. ASSERT_EQ(b.at(3), 0);
  32. }
  33. TEST(CudaPlugin, SpMV_4x4_float) {
  34. storm::storage::SparseMatrixBuilder<float> matrixBuilder(4, 4, 10);
  35. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0f));
  36. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 3, -1.0f));
  37. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 8.0f));
  38. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 7.0f));
  39. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 2, -5.0f));
  40. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 2.0f));
  41. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 2.0f));
  42. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 1, 2.0f));
  43. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 2, 4.0f));
  44. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 3, 4.0f));
  45. storm::storage::SparseMatrix<float> matrix;
  46. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  47. ASSERT_EQ(4, matrix.getRowCount());
  48. ASSERT_EQ(4, matrix.getColumnCount());
  49. ASSERT_EQ(10, matrix.getEntryCount());
  50. std::vector<float> x({ 0.f, 4.f, 1.f, 1.f });
  51. std::vector<float> b({ 0.f, 0.f, 0.f, 0.f });
  52. ASSERT_NO_THROW(basicValueIteration_spmv_uint64_float(matrix.getColumnCount(), matrix.__internal_getRowIndications(), matrix.__internal_getColumnsAndValues(), x, b));
  53. ASSERT_EQ(b.at(0), 3);
  54. ASSERT_EQ(b.at(1), 25);
  55. ASSERT_EQ(b.at(2), 16);
  56. ASSERT_EQ(b.at(3), 0);
  57. }
  58. TEST(CudaPlugin, SpMV_VerySmall) {
  59. storm::storage::SparseMatrixBuilder<double> matrixBuilder(2, 2, 2);
  60. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 0, 1.0));
  61. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 2.0));
  62. storm::storage::SparseMatrix<double> matrix;
  63. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  64. ASSERT_EQ(2, matrix.getRowCount());
  65. ASSERT_EQ(2, matrix.getColumnCount());
  66. ASSERT_EQ(2, matrix.getEntryCount());
  67. std::vector<double> x({ 4.0, 8.0 });
  68. std::vector<double> b({ 0.0, 0.0 });
  69. ASSERT_NO_THROW(basicValueIteration_spmv_uint64_double(matrix.getColumnCount(), matrix.__internal_getRowIndications(), matrix.__internal_getColumnsAndValues(), x, b));
  70. ASSERT_EQ(b.at(0), 4.0);
  71. ASSERT_EQ(b.at(1), 16.0);
  72. }
  73. TEST(CudaPlugin, SpMV_VerySmall_float) {
  74. storm::storage::SparseMatrixBuilder<float> matrixBuilder(2, 2, 2);
  75. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 0, 1.0));
  76. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 2.0));
  77. storm::storage::SparseMatrix<float> matrix;
  78. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  79. ASSERT_EQ(2, matrix.getRowCount());
  80. ASSERT_EQ(2, matrix.getColumnCount());
  81. ASSERT_EQ(2, matrix.getEntryCount());
  82. std::vector<float> x({ 4.0, 8.0 });
  83. std::vector<float> b({ 0.0, 0.0 });
  84. ASSERT_NO_THROW(basicValueIteration_spmv_uint64_float(matrix.getColumnCount(), matrix.__internal_getRowIndications(), matrix.__internal_getColumnsAndValues(), x, b));
  85. ASSERT_EQ(b.at(0), 4.0);
  86. ASSERT_EQ(b.at(1), 16.0);
  87. }
  88. TEST(CudaPlugin, AddVectorsInplace) {
  89. std::vector<double> vectorA_1 = { 0.0, 42.0, 21.4, 3.1415, 1.0, 7.3490390, 94093053905390.21, -0.000000000023 };
  90. std::vector<double> vectorA_2 = { 0.0, 42.0, 21.4, 3.1415, 1.0, 7.3490390, 94093053905390.21, -0.000000000023 };
  91. std::vector<double> vectorA_3 = { 0.0, 42.0, 21.4, 3.1415, 1.0, 7.3490390, 94093053905390.21, -0.000000000023 };
  92. std::vector<double> vectorB = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
  93. std::vector<double> vectorC = { -5000.0, -5000.0, -5000.0, -5000.0, -5000.0, -5000.0, -5000.0, -5000.0 };
  94. ASSERT_EQ(vectorA_1.size(), 8);
  95. ASSERT_EQ(vectorA_2.size(), 8);
  96. ASSERT_EQ(vectorA_3.size(), 8);
  97. ASSERT_EQ(vectorB.size(), 8);
  98. ASSERT_EQ(vectorC.size(), 8);
  99. ASSERT_NO_THROW(basicValueIteration_addVectorsInplace_double(vectorA_1, vectorB));
  100. ASSERT_NO_THROW(basicValueIteration_addVectorsInplace_double(vectorA_2, vectorC));
  101. ASSERT_EQ(vectorA_1.size(), 8);
  102. ASSERT_EQ(vectorA_2.size(), 8);
  103. ASSERT_EQ(vectorA_3.size(), 8);
  104. ASSERT_EQ(vectorB.size(), 8);
  105. ASSERT_EQ(vectorC.size(), 8);
  106. for (size_t i = 0; i < vectorA_3.size(); ++i) {
  107. double cpu_result_b = vectorA_3.at(i) + vectorB.at(i);
  108. double cpu_result_c = vectorA_3.at(i) + vectorC.at(i);
  109. ASSERT_EQ(cpu_result_b, vectorA_1.at(i));
  110. ASSERT_EQ(cpu_result_c, vectorA_2.at(i));
  111. }
  112. }
  113. TEST(CudaPlugin, AddVectorsInplace_float) {
  114. std::vector<float> vectorA_1 = { 0.0f, 42.0f, 21.4f, 3.1415f, 1.0f, 7.3490390f, 94093053905390.21f, -0.000000000023f };
  115. std::vector<float> vectorA_2 = { 0.0f, 42.0f, 21.4f, 3.1415f, 1.0f, 7.3490390f, 94093053905390.21f, -0.000000000023f };
  116. std::vector<float> vectorA_3 = { 0.0f, 42.0f, 21.4f, 3.1415f, 1.0f, 7.3490390f, 94093053905390.21f, -0.000000000023f };
  117. std::vector<float> vectorB = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
  118. std::vector<float> vectorC = { -5000.0f, -5000.0f, -5000.0f, -5000.0f, -5000.0f, -5000.0f, -5000.0f, -5000.0f };
  119. ASSERT_EQ(vectorA_1.size(), 8);
  120. ASSERT_EQ(vectorA_2.size(), 8);
  121. ASSERT_EQ(vectorA_3.size(), 8);
  122. ASSERT_EQ(vectorB.size(), 8);
  123. ASSERT_EQ(vectorC.size(), 8);
  124. ASSERT_NO_THROW(basicValueIteration_addVectorsInplace_float(vectorA_1, vectorB));
  125. ASSERT_NO_THROW(basicValueIteration_addVectorsInplace_float(vectorA_2, vectorC));
  126. ASSERT_EQ(vectorA_1.size(), 8);
  127. ASSERT_EQ(vectorA_2.size(), 8);
  128. ASSERT_EQ(vectorA_3.size(), 8);
  129. ASSERT_EQ(vectorB.size(), 8);
  130. ASSERT_EQ(vectorC.size(), 8);
  131. for (size_t i = 0; i < vectorA_3.size(); ++i) {
  132. float cpu_result_b = vectorA_3.at(i) + vectorB.at(i);
  133. float cpu_result_c = vectorA_3.at(i) + vectorC.at(i);
  134. ASSERT_EQ(cpu_result_b, vectorA_1.at(i));
  135. ASSERT_EQ(cpu_result_c, vectorA_2.at(i));
  136. }
  137. }
  138. TEST(CudaPlugin, ReduceGroupedVector) {
  139. std::vector<double> groupedVector = {
  140. 0.0, -1000.0, 0.000004, // Group 0
  141. 5.0, // Group 1
  142. 0.0, 1.0, 2.0, 3.0, // Group 2
  143. -1000.0, -3.14, -0.0002,// Group 3 (neg only)
  144. 25.25, 25.25, 25.25, // Group 4
  145. 0.0, 0.0, 1.0, // Group 5
  146. -0.000001, 0.000001 // Group 6
  147. };
  148. std::vector<uint_fast64_t> grouping = {
  149. 0, 3, 4, 8, 11, 14, 17, 19
  150. };
  151. std::vector<double> result_minimize = {
  152. -1000.0, // Group 0
  153. 5.0,
  154. 0.0,
  155. -1000.0,
  156. 25.25,
  157. 0.0,
  158. -0.000001
  159. };
  160. std::vector<double> result_maximize = {
  161. 0.000004,
  162. 5.0,
  163. 3.0,
  164. -0.0002,
  165. 25.25,
  166. 1.0,
  167. 0.000001
  168. };
  169. std::vector<double> result_cuda_minimize = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
  170. std::vector<double> result_cuda_maximize = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
  171. ASSERT_NO_THROW(basicValueIteration_reduceGroupedVector_uint64_double_minimize(groupedVector, grouping, result_cuda_minimize));
  172. ASSERT_NO_THROW(basicValueIteration_reduceGroupedVector_uint64_double_maximize(groupedVector, grouping, result_cuda_maximize));
  173. for (size_t i = 0; i < result_minimize.size(); ++i) {
  174. ASSERT_EQ(result_minimize.at(i), result_cuda_minimize.at(i));
  175. ASSERT_EQ(result_maximize.at(i), result_cuda_maximize.at(i));
  176. }
  177. }
  178. TEST(CudaPlugin, ReduceGroupedVector_float) {
  179. std::vector<float> groupedVector = {
  180. 0.0f, -1000.0f, 0.000004f, // Group 0
  181. 5.0f, // Group 1
  182. 0.0f, 1.0f, 2.0f, 3.0f, // Group 2
  183. -1000.0f, -3.14f, -0.0002f,// Group 3 (neg only)
  184. 25.25f, 25.25f, 25.25f, // Group 4
  185. 0.0f, 0.0f, 1.0f, // Group 5
  186. -0.000001f, 0.000001f // Group 6
  187. };
  188. std::vector<uint_fast64_t> grouping = {
  189. 0, 3, 4, 8, 11, 14, 17, 19
  190. };
  191. std::vector<float> result_minimize = {
  192. -1000.0f, // Group 0
  193. 5.0f,
  194. 0.0f,
  195. -1000.0f,
  196. 25.25f,
  197. 0.0f,
  198. -0.000001f
  199. };
  200. std::vector<float> result_maximize = {
  201. 0.000004f,
  202. 5.0f,
  203. 3.0f,
  204. -0.0002f,
  205. 25.25f,
  206. 1.0f,
  207. 0.000001f
  208. };
  209. std::vector<float> result_cuda_minimize = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
  210. std::vector<float> result_cuda_maximize = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
  211. ASSERT_NO_THROW(basicValueIteration_reduceGroupedVector_uint64_float_minimize(groupedVector, grouping, result_cuda_minimize));
  212. ASSERT_NO_THROW(basicValueIteration_reduceGroupedVector_uint64_float_maximize(groupedVector, grouping, result_cuda_maximize));
  213. for (size_t i = 0; i < result_minimize.size(); ++i) {
  214. ASSERT_EQ(result_minimize.at(i), result_cuda_minimize.at(i));
  215. ASSERT_EQ(result_maximize.at(i), result_cuda_maximize.at(i));
  216. }
  217. }
  218. TEST(CudaPlugin, equalModuloPrecision) {
  219. std::vector<double> x = {
  220. 123.45, 67.8, 901.23, 456789.012, 3.456789, -4567890.12
  221. };
  222. std::vector<double> y1 = {
  223. 0.45, 0.8, 0.23, 0.012, 0.456789, -0.12
  224. };
  225. std::vector<double> y2 = {
  226. 0.45, 0.8, 0.23, 456789.012, 0.456789, -4567890.12
  227. };
  228. std::vector<double> x2;
  229. std::vector<double> x3;
  230. std::vector<double> y3;
  231. std::vector<double> y4;
  232. x2.reserve(1000);
  233. x3.reserve(1000);
  234. y3.reserve(1000);
  235. y4.reserve(1000);
  236. for (size_t i = 0; i < 1000; ++i) {
  237. x2.push_back(static_cast<double>(i));
  238. y3.push_back(1.0);
  239. x3.push_back(-(1000.0 - static_cast<double>(i)));
  240. y4.push_back(1.0);
  241. }
  242. double maxElement1 = 0.0;
  243. double maxElement2 = 0.0;
  244. double maxElement3 = 0.0;
  245. double maxElement4 = 0.0;
  246. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_double_NonRelative(x, y1, maxElement1));
  247. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_double_NonRelative(x, y2, maxElement2));
  248. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_double_Relative(x2, y3, maxElement3));
  249. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_double_Relative(x3, y4, maxElement4));
  250. ASSERT_DOUBLE_EQ(4567890.0, maxElement1);
  251. ASSERT_DOUBLE_EQ(901.0, maxElement2);
  252. ASSERT_DOUBLE_EQ(998.0, maxElement3);
  253. ASSERT_DOUBLE_EQ(1001.0, maxElement4);
  254. }
  255. TEST(CudaPlugin, equalModuloPrecision_float) {
  256. std::vector<float> x = {
  257. 123.45f, 67.8f, 901.23f, 456789.012f, 3.456789f, -4567890.12f
  258. };
  259. std::vector<float> y1 = {
  260. 0.45f, 0.8f, 0.23f, 0.012f, 0.456789f, -0.12f
  261. };
  262. std::vector<float> y2 = {
  263. 0.45f, 0.8f, 0.23f, 456789.012f, 0.456789f, -4567890.12f
  264. };
  265. std::vector<float> x2;
  266. std::vector<float> x3;
  267. std::vector<float> y3;
  268. std::vector<float> y4;
  269. x2.reserve(1000);
  270. x3.reserve(1000);
  271. y3.reserve(1000);
  272. y4.reserve(1000);
  273. for (size_t i = 0; i < 1000; ++i) {
  274. x2.push_back(static_cast<float>(i));
  275. y3.push_back(1.0f);
  276. x3.push_back(-(1000.0f - static_cast<float>(i)));
  277. y4.push_back(1.0f);
  278. }
  279. float maxElement1 = 0.0f;
  280. float maxElement2 = 0.0f;
  281. float maxElement3 = 0.0f;
  282. float maxElement4 = 0.0f;
  283. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_float_NonRelative(x, y1, maxElement1));
  284. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_float_NonRelative(x, y2, maxElement2));
  285. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_float_Relative(x2, y3, maxElement3));
  286. ASSERT_NO_THROW(basicValueIteration_equalModuloPrecision_float_Relative(x3, y4, maxElement4));
  287. ASSERT_DOUBLE_EQ(4567890.0f, maxElement1);
  288. ASSERT_DOUBLE_EQ(901.0f, maxElement2);
  289. ASSERT_DOUBLE_EQ(998.0f, maxElement3);
  290. ASSERT_DOUBLE_EQ(1001.0f, maxElement4);
  291. }
  292. #endif