1 /*
2 * Copyright (c) 2013-2021, The OSKAR Developers.
3 * See the LICENSE file at the top-level directory of this distribution.
4 */
5
6 #include <gtest/gtest.h>
7
8 #include "utility/oskar_get_error_string.h"
9 #include "mem/oskar_mem.h"
10 #include <cstdio>
11
TEST(Mem,load_ascii_single_column)12 TEST(Mem, load_ascii_single_column)
13 {
14 int status = 0;
15
16 // Write a test file.
17 const char* filename = "temp_test_load_ascii_single_column.txt";
18 FILE* file = fopen(filename, "w");
19 ASSERT_TRUE(file != NULL);
20 size_t i = 0, num_elements = 13;
21 fprintf(file, "# A header\n");
22 for (; i < num_elements; ++i) fprintf(file, "%.3f\n", i * 1.0);
23 fprintf(file, "# A comment\n");
24 for (; i < 2 * num_elements; ++i) fprintf(file, "%.3f\n", i * 1.0);
25 fprintf(file, " # A silly comment\n");
26 for (; i < 3 * num_elements; ++i) fprintf(file, "%.3f\n", i * 1.0);
27 fclose(file);
28
29 // Load column back into CPU memory.
30 oskar_Mem *a = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
31 ASSERT_EQ(0, status) << oskar_get_error_string(status);
32 oskar_mem_load_ascii(filename, 1, &status, a, "");
33 ASSERT_EQ(0, status) << oskar_get_error_string(status);
34 ASSERT_EQ(3 * num_elements, oskar_mem_length(a));
35
36 // Check contents.
37 const double* a_ = oskar_mem_double_const(a, &status);
38 for (i = 0; i < 3 * num_elements; ++i)
39 {
40 ASSERT_NEAR(a_[i], i * 1.0, 1e-10);
41 }
42
43 oskar_mem_free(a, &status);
44 remove(filename);
45 }
46
TEST(Mem,load_ascii_real_cpu)47 TEST(Mem, load_ascii_real_cpu)
48 {
49 int status = 0;
50
51 // Write a test file.
52 const char* filename = "temp_test_load_ascii_real.txt";
53 FILE* file = fopen(filename, "w");
54 ASSERT_TRUE(file != NULL);
55 int num_elements = 287;
56 for (int i = 0; i < num_elements; ++i)
57 {
58 fprintf(file, "%.3f %.3f %.3f, %.5e\n", i * 1.0, i * 10.0, i * 100.0,
59 i * 1000.0);
60 }
61 fclose(file);
62
63 // Load columns back into CPU memory.
64 oskar_Mem *a = 0, *b = 0, *c = 0, *d = 0;
65 a = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
66 b = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
67 c = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
68 d = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
69 ASSERT_EQ(0, status) << oskar_get_error_string(status);
70
71 // Expect pass.
72 oskar_mem_load_ascii(filename, 4, &status, a, "0.0", b, "0.0",
73 c, "0.0", d, "0.0");
74 ASSERT_EQ(0, status) << oskar_get_error_string(status);
75
76 // Check contents.
77 const double* a_ = oskar_mem_double_const(a, &status);
78 const double* b_ = oskar_mem_double_const(b, &status);
79 const double* c_ = oskar_mem_double_const(c, &status);
80 const double* d_ = oskar_mem_double_const(d, &status);
81 for (int i = 0; i < num_elements; ++i)
82 {
83 ASSERT_NEAR(a_[i], i * 1.0, 1e-10);
84 ASSERT_NEAR(b_[i], i * 10.0, 1e-10);
85 ASSERT_NEAR(c_[i], i * 100.0, 1e-10);
86 ASSERT_NEAR(d_[i], i * 1000.0, 1e-10);
87 }
88
89 oskar_mem_free(a, &status);
90 oskar_mem_free(b, &status);
91 oskar_mem_free(c, &status);
92 oskar_mem_free(d, &status);
93
94 remove(filename);
95 }
96
97
98 #ifdef OSKAR_HAVE_CUDA
TEST(Mem,load_ascii_real_gpu)99 TEST(Mem, load_ascii_real_gpu)
100 {
101 int status = 0;
102
103 // Write a test file.
104 const char* filename = "temp_test_load_ascii_real_gpu.txt";
105 FILE* file = fopen(filename, "w");
106 ASSERT_TRUE(file != NULL);
107 int num_elements = 474;
108 for (int i = 0; i < num_elements; ++i)
109 {
110 fprintf(file, "%.3f %.3f %.3f, %.5e\n", i * 1.0, i * 10.0, i * 100.0,
111 i * 1000.0);
112 }
113 fclose(file);
114
115 // Load columns back into GPU memory.
116 oskar_Mem *a = 0, *b = 0, *c = 0, *d = 0;
117 a = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, 0, &status);
118 b = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, 0, &status);
119 c = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, 0, &status);
120 d = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, 0, &status);
121 ASSERT_EQ(0, status) << oskar_get_error_string(status);
122
123 // Expect pass.
124 oskar_mem_load_ascii(filename, 4, &status, a, "0.0", b, "0.0",
125 c, "0.0", d, "0.0");
126 ASSERT_EQ(0, status) << oskar_get_error_string(status);
127
128 // Copy to CPU memory to check contents.
129 oskar_Mem *aa = 0, *bb = 0, *cc = 0, *dd = 0;
130 aa = oskar_mem_create_copy(a, OSKAR_CPU, &status);
131 bb = oskar_mem_create_copy(b, OSKAR_CPU, &status);
132 cc = oskar_mem_create_copy(c, OSKAR_CPU, &status);
133 dd = oskar_mem_create_copy(d, OSKAR_CPU, &status);
134 const double* a_ = oskar_mem_double_const(aa, &status);
135 const double* b_ = oskar_mem_double_const(bb, &status);
136 const double* c_ = oskar_mem_double_const(cc, &status);
137 const double* d_ = oskar_mem_double_const(dd, &status);
138 for (int i = 0; i < num_elements; ++i)
139 {
140 ASSERT_NEAR(a_[i], i * 1.0, 1e-10);
141 ASSERT_NEAR(b_[i], i * 10.0, 1e-10);
142 ASSERT_NEAR(c_[i], i * 100.0, 1e-10);
143 ASSERT_NEAR(d_[i], i * 1000.0, 1e-10);
144 }
145
146 oskar_mem_free(a, &status);
147 oskar_mem_free(b, &status);
148 oskar_mem_free(c, &status);
149 oskar_mem_free(d, &status);
150 oskar_mem_free(aa, &status);
151 oskar_mem_free(bb, &status);
152 oskar_mem_free(cc, &status);
153 oskar_mem_free(dd, &status);
154
155 remove(filename);
156 }
157 #endif
158
159
TEST(Mem,load_ascii_complex_real_cpu)160 TEST(Mem, load_ascii_complex_real_cpu)
161 {
162 int status = 0;
163
164 // Write a test file.
165 const char* filename = "temp_test_load_ascii_complex_real_cpu.txt";
166 FILE* file = fopen(filename, "w");
167 ASSERT_TRUE(file != NULL);
168 int num_elements = 326;
169 for (int i = 0; i < num_elements; ++i)
170 {
171 fprintf(file, "%.3f %.3f, %.5e\n", i * 1.0, i * 10.0, i * 100.0);
172 }
173 fclose(file);
174
175 // Load columns back into CPU memory.
176 oskar_Mem *a = 0, *b = 0;
177 a = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, 0, &status);
178 b = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
179 ASSERT_EQ(0, status) << oskar_get_error_string(status);
180
181 // Wrong default: expect failure.
182 oskar_mem_load_ascii(filename, 2, &status, a, "1.0", b, "0.0");
183 ASSERT_NE(0, status);
184 status = 0;
185
186 // Expect pass.
187 oskar_mem_load_ascii(filename, 2, &status, a, "1.0 0.0", b, "0.0");
188 ASSERT_EQ(0, status) << oskar_get_error_string(status);
189
190 // Check contents.
191 const double2* a_ = oskar_mem_double2_const(a, &status);
192 const double* b_ = oskar_mem_double_const(b, &status);
193 for (int i = 0; i < num_elements; ++i)
194 {
195 ASSERT_NEAR(a_[i].x, i * 1.0, 1e-10);
196 ASSERT_NEAR(a_[i].y, i * 10.0, 1e-10);
197 ASSERT_NEAR(b_[i], i * 100.0, 1e-10);
198 }
199
200 oskar_mem_free(a, &status);
201 oskar_mem_free(b, &status);
202
203 remove(filename);
204 }
205
206
207 #ifdef OSKAR_HAVE_CUDA
TEST(Mem,load_ascii_complex_real_gpu_cpu)208 TEST(Mem, load_ascii_complex_real_gpu_cpu)
209 {
210 int status = 0;
211
212 // Write a test file.
213 const char* filename = "temp_test_load_ascii_complex_real_gpu_cpu.txt";
214 FILE* file = fopen(filename, "w");
215 ASSERT_TRUE(file != NULL);
216 int num_elements = 753;
217 for (int i = 0; i < num_elements; ++i)
218 {
219 fprintf(file, "%.3f %.3f, %.5e\n", i * 1.0, i * 10.0, i * 100.0);
220 }
221 fclose(file);
222
223 // Load columns back into CPU memory.
224 oskar_Mem *a = 0, *b = 0;
225 a = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_GPU, 0, &status);
226 b = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
227 ASSERT_EQ(0, status) << oskar_get_error_string(status);
228
229 // Wrong default: expect failure.
230 oskar_mem_load_ascii(filename, 2, &status, a, "1.0", b, "0.0");
231 ASSERT_NE(0, status);
232 status = 0;
233
234 // Expect pass.
235 oskar_mem_load_ascii(filename, 2, &status, a, "1.0 0.0", b, "0.0");
236 ASSERT_EQ(0, status) << oskar_get_error_string(status);
237
238 // Check contents.
239 oskar_Mem *aa = oskar_mem_create_copy(a, OSKAR_CPU, &status);
240 const double2* a_ = oskar_mem_double2_const(aa, &status);
241 const double* b_ = oskar_mem_double_const(b, &status);
242 for (int i = 0; i < num_elements; ++i)
243 {
244 ASSERT_NEAR(a_[i].x, i * 1.0, 1e-10);
245 ASSERT_NEAR(a_[i].y, i * 10.0, 1e-10);
246 ASSERT_NEAR(b_[i], i * 100.0, 1e-10);
247 }
248
249 oskar_mem_free(a, &status);
250 oskar_mem_free(b, &status);
251 oskar_mem_free(aa, &status);
252
253 remove(filename);
254 }
255 #endif
256
257
TEST(Mem,load_ascii_complex_real_default_cpu)258 TEST(Mem, load_ascii_complex_real_default_cpu)
259 {
260 int status = 0;
261
262 // Write a test file.
263 const char* filename = "temp_test_load_ascii_complex_real_default_cpu.txt";
264 FILE* file = fopen(filename, "w");
265 ASSERT_TRUE(file != NULL);
266 int num_elements = 89;
267 for (int i = 0; i < num_elements; ++i)
268 {
269 fprintf(file, "%.3f %.3f\n", i * 1.0, i * 10.0);
270 }
271 fclose(file);
272
273 // Load columns back into CPU memory.
274 oskar_Mem *a = 0, *b = 0, *c = 0;
275 a = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, 0, &status);
276 b = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
277 c = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
278 ASSERT_EQ(0, status) << oskar_get_error_string(status);
279
280 // Wrong default: expect failure.
281 oskar_mem_load_ascii(filename, 2, &status, a, "1.0", b, "0.0");
282 ASSERT_NE(0, status);
283 status = 0;
284
285 // Badly placed default: expect failure.
286 oskar_mem_load_ascii(filename, 3, &status, a, "", b, "9.9", c, "");
287 ASSERT_NE(0, status);
288 status = 0;
289
290 // Expect pass.
291 oskar_mem_load_ascii(filename, 3, &status, a, "1.0 0.0", b, "5.1", c, "2.5");
292 ASSERT_EQ(0, status) << oskar_get_error_string(status);
293
294 // Check contents.
295 const double2* a_ = oskar_mem_double2_const(a, &status);
296 const double* b_ = oskar_mem_double_const(b, &status);
297 const double* c_ = oskar_mem_double_const(c, &status);
298 for (int i = 0; i < num_elements; ++i)
299 {
300 ASSERT_NEAR(a_[i].x, i * 1.0, 1e-10);
301 ASSERT_NEAR(a_[i].y, i * 10.0, 1e-10);
302 ASSERT_NEAR(b_[i], 5.1, 1e-10);
303 ASSERT_NEAR(c_[i], 2.5, 1e-10);
304 }
305
306 oskar_mem_free(a, &status);
307 oskar_mem_free(b, &status);
308 oskar_mem_free(c, &status);
309
310 remove(filename);
311 }
312
TEST(Mem,load_ascii_lots_of_columns)313 TEST(Mem, load_ascii_lots_of_columns)
314 {
315 int status = 0;
316
317 // Write a test file.
318 const char* filename = "temp_test_load_ascii_lots_of_columns.txt";
319 FILE* file = fopen(filename, "w");
320 ASSERT_TRUE(file != NULL);
321 int num_elements = 119;
322 for (int i = 0; i < num_elements; ++i)
323 {
324 fprintf(file, "%.3f %.3f %.3f, %.3f, %.3f\n", i * 1.0, i * 10.0,
325 i * 20.0, i * 23.0, i * 25.5);
326 }
327 fclose(file);
328
329 // Load some columns back into CPU memory.
330 oskar_Mem *a = 0, *b = 0, *c = 0;
331 a = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, 0, &status);
332 b = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
333 c = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
334 ASSERT_EQ(0, status) << oskar_get_error_string(status);
335
336 // Expect pass.
337 oskar_mem_load_ascii(filename, 3, &status, a, "", b, "", c, "");
338 ASSERT_EQ(0, status) << oskar_get_error_string(status);
339
340 // Check contents.
341 const double2* a_ = oskar_mem_double2_const(a, &status);
342 const double* b_ = oskar_mem_double_const(b, &status);
343 const double* c_ = oskar_mem_double_const(c, &status);
344 for (int i = 0; i < num_elements; ++i)
345 {
346 ASSERT_NEAR(a_[i].x, i * 1.0, 1e-10);
347 ASSERT_NEAR(a_[i].y, i * 10.0, 1e-10);
348 ASSERT_NEAR(b_[i], i * 20.0, 1e-10);
349 ASSERT_NEAR(c_[i], i * 23.0, 1e-10);
350 }
351
352 oskar_mem_free(a, &status);
353 oskar_mem_free(b, &status);
354 oskar_mem_free(c, &status);
355
356 remove(filename);
357 }
358
TEST(Mem,load_ascii_required_data)359 TEST(Mem, load_ascii_required_data)
360 {
361 int status = 0;
362
363 // Write a test file.
364 const char* filename = "temp_test_load_ascii_required_data.txt";
365 FILE* file = fopen(filename, "w");
366 ASSERT_TRUE(file != NULL);
367 int num_elements = 119;
368 for (int i = 0; i < num_elements; ++i)
369 {
370 fprintf(file, "%.3f %.3f %.3f, %.3f, %.3f\n", i * 1.0, i * 10.0,
371 i * 20.0, i * 23.0, i * 25.5);
372 }
373 fprintf(file, "%.3f\n", 123456.789); // Write a line without enough columns.
374 fprintf(file, "%.3f %.3f\n", 11.1, 22.2); // This one should be OK.
375 for (int i = 0; i < num_elements; ++i)
376 {
377 fprintf(file, "%.3f %.3f %.3f, %.3f, %.3f\n", i * 1.0, i * 10.0,
378 i * 20.0, i * 23.0, i * 25.5);
379 }
380 fclose(file);
381
382 // Load some columns back into CPU memory.
383 oskar_Mem *a = 0, *b = 0, *c = 0;
384 a = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
385 b = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
386 c = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
387 ASSERT_EQ(0, status) << oskar_get_error_string(status);
388
389 // Expect pass.
390 oskar_mem_load_ascii(filename, 3, &status, a, "", b, "", c, "3.3");
391 ASSERT_EQ(0, status) << oskar_get_error_string(status);
392
393 // Check arrays are the right length.
394 EXPECT_EQ(2 * num_elements + 1, (int)oskar_mem_length(a));
395 EXPECT_EQ(2 * num_elements + 1, (int)oskar_mem_length(b));
396 EXPECT_EQ(2 * num_elements + 1, (int)oskar_mem_length(c));
397
398 // Check contents.
399 const double* a_ = oskar_mem_double_const(a, &status);
400 const double* b_ = oskar_mem_double_const(b, &status);
401 const double* c_ = oskar_mem_double_const(c, &status);
402 // a_[i] must always be less than 10000, because no default was
403 // supplied for b where that value was set for a.
404 for (int i = 0; i < num_elements; ++i)
405 {
406 ASSERT_NEAR(a_[i], i * 1.0, 1e-10);
407 ASSERT_LT(a_[i], 10000.0);
408 ASSERT_NEAR(b_[i], i * 10.0, 1e-10);
409 ASSERT_NEAR(c_[i], i * 20.0, 1e-10);
410 }
411 ASSERT_EQ(11.1, a_[num_elements]);
412 ASSERT_EQ(22.2, b_[num_elements]);
413 ASSERT_EQ(3.3, c_[num_elements]);
414 for (int i = 0; i < num_elements; ++i)
415 {
416 int j = i + num_elements + 1;
417 ASSERT_NEAR(a_[j], i * 1.0, 1e-10);
418 ASSERT_LT(a_[j], 10000.0);
419 ASSERT_NEAR(b_[j], i * 10.0, 1e-10);
420 ASSERT_NEAR(c_[j], i * 20.0, 1e-10);
421 }
422
423 oskar_mem_free(a, &status);
424 oskar_mem_free(b, &status);
425 oskar_mem_free(c, &status);
426
427 remove(filename);
428 }
429
430
TEST(Mem,save_ascii)431 TEST(Mem, save_ascii)
432 {
433 int status = 0, location = OSKAR_CPU;
434 oskar_Mem *mem1 = 0, *mem2 = 0, *mem3 = 0, *mem4 = 0, *mem5 = 0, *mem6 = 0, *mem7 = 0, *mem8 = 0;
435 size_t length = 100;
436 #ifdef OSKAR_HAVE_CUDA
437 location = OSKAR_GPU;
438 #endif
439 mem1 = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, length, &status);
440 mem2 = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, length, &status);
441 mem3 = oskar_mem_create(OSKAR_SINGLE_COMPLEX, OSKAR_CPU, length, &status);
442 mem4 = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, length, &status);
443 mem5 = oskar_mem_create(OSKAR_SINGLE, location, length, &status);
444 mem6 = oskar_mem_create(OSKAR_DOUBLE, location, length, &status);
445 mem7 = oskar_mem_create(OSKAR_SINGLE_COMPLEX, location, length, &status);
446 mem8 = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, location, length, &status);
447 ASSERT_EQ(0, status) << oskar_get_error_string(status);
448
449 oskar_mem_set_value_real(mem1, 1.0, 0, length, &status);
450 oskar_mem_set_value_real(mem2, 2.0, 0, length, &status);
451 oskar_mem_set_value_real(mem3, 3.0, 0, length, &status);
452 oskar_mem_set_value_real(mem4, 4.0, 0, length, &status);
453 oskar_mem_set_value_real(mem5, 5.0, 0, length, &status);
454 oskar_mem_set_value_real(mem6, 6.0, 0, length, &status);
455 oskar_mem_set_value_real(mem7, 7.0, 0, length, &status);
456 oskar_mem_set_value_real(mem8, 8.0, 0, length, &status);
457
458 const char* fname = "temp_test_save_ascii.txt";
459 FILE* f = fopen(fname, "w");
460 ASSERT_TRUE(f != NULL);
461 oskar_mem_save_ascii(f, 8, 0, length, &status,
462 mem1, mem2, mem3, mem4, mem5, mem6, mem7, mem8);
463 fclose(f);
464 ASSERT_EQ(0, status) << oskar_get_error_string(status);
465
466 oskar_mem_free(mem1, &status);
467 oskar_mem_free(mem2, &status);
468 oskar_mem_free(mem3, &status);
469 oskar_mem_free(mem4, &status);
470 oskar_mem_free(mem5, &status);
471 oskar_mem_free(mem6, &status);
472 oskar_mem_free(mem7, &status);
473 oskar_mem_free(mem8, &status);
474 ASSERT_EQ(0, status) << oskar_get_error_string(status);
475 remove(fname);
476 }
477