static void check_values(const oskar_Mem* approx, const oskar_Mem* accurate) { int status = 0; double min_rel_error, max_rel_error, avg_rel_error, std_rel_error, tol; oskar_mem_evaluate_relative_error(approx, accurate, &min_rel_error, &max_rel_error, &avg_rel_error, &std_rel_error, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); tol = oskar_mem_is_double(approx) && oskar_mem_is_double(accurate) ? 1e-11 : 2e-3; EXPECT_LT(max_rel_error, tol) << std::setprecision(5) << "RELATIVE ERROR" << " MIN: " << min_rel_error << " MAX: " << max_rel_error << " AVG: " << avg_rel_error << " STD: " << std_rel_error; tol = oskar_mem_is_double(approx) && oskar_mem_is_double(accurate) ? 1e-12 : 1e-5; EXPECT_LT(avg_rel_error, tol) << std::setprecision(5) << "RELATIVE ERROR" << " MIN: " << min_rel_error << " MAX: " << max_rel_error << " AVG: " << avg_rel_error << " STD: " << std_rel_error; }
TEST(Mem, random_uniform) { int seed = 1; int c1 = 437; int c2 = 0; int c3 = 0xDECAFBAD; int n = 544357; int status = 0; double max_err = 0.0, avg_err = 0.0; oskar_Mem* v_cpu_f = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, n, &status); oskar_Mem* v_gpu_f = oskar_mem_create(OSKAR_SINGLE, OSKAR_GPU, n, &status); oskar_Mem* v_cpu_d = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, n, &status); oskar_Mem* v_gpu_d = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, n, &status); oskar_Timer* tmr = oskar_timer_create(OSKAR_TIMER_CUDA); // Run in single precision. oskar_timer_start(tmr); oskar_mem_random_uniform(v_cpu_f, seed, c1, c2, c3, &status); report_time(n, "uniform", "single", "CPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_timer_start(tmr); oskar_mem_random_uniform(v_gpu_f, seed, c1, c2, c3, &status); report_time(n, "uniform", "single", "GPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check consistency between CPU and GPU results. oskar_mem_evaluate_relative_error(v_gpu_f, v_cpu_f, 0, &max_err, &avg_err, 0, &status); EXPECT_LT(max_err, 1e-5); EXPECT_LT(avg_err, 1e-5); // Run in double precision. oskar_timer_start(tmr); oskar_mem_random_uniform(v_cpu_d, seed, c1, c2, c3, &status); report_time(n, "uniform", "double", "CPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_timer_start(tmr); oskar_mem_random_uniform(v_gpu_d, seed, c1, c2, c3, &status); report_time(n, "uniform", "double", "GPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check consistency between CPU and GPU results. oskar_mem_evaluate_relative_error(v_gpu_d, v_cpu_d, 0, &max_err, &avg_err, 0, &status); EXPECT_LT(max_err, 1e-10); EXPECT_LT(avg_err, 1e-10); // Check consistency between single and double precision. oskar_mem_evaluate_relative_error(v_cpu_f, v_cpu_d, 0, &max_err, &avg_err, 0, &status); EXPECT_LT(max_err, 1e-5); EXPECT_LT(avg_err, 1e-5); if (save) { FILE* fhan = fopen("random_uniform.txt", "w"); oskar_mem_save_ascii(fhan, 4, n, &status, v_cpu_f, v_gpu_f, v_cpu_d, v_gpu_d); fclose(fhan); } // Free memory. oskar_mem_free(v_cpu_f, &status); oskar_mem_free(v_gpu_f, &status); oskar_mem_free(v_cpu_d, &status); oskar_mem_free(v_gpu_d, &status); oskar_timer_free(tmr); }
TEST(evaluate_baselines, cpu_gpu) { oskar_Mem *u, *v, *w, *uu, *vv, *ww; oskar_Mem *u_gpu, *v_gpu, *w_gpu, *uu_gpu, *vv_gpu, *ww_gpu; int num_baselines, num_stations = 50, status = 0, type, location; double *u_, *v_, *w_, *uu_, *vv_, *ww_; num_baselines = num_stations * (num_stations - 1) / 2; type = OSKAR_DOUBLE; // Allocate host memory. location = OSKAR_CPU; u = oskar_mem_create(type, location, num_stations, &status); v = oskar_mem_create(type, location, num_stations, &status); w = oskar_mem_create(type, location, num_stations, &status); uu = oskar_mem_create(type, location, num_baselines, &status); vv = oskar_mem_create(type, location, num_baselines, &status); ww = oskar_mem_create(type, location, num_baselines, &status); u_ = oskar_mem_double(u, &status); v_ = oskar_mem_double(v, &status); w_ = oskar_mem_double(w, &status); uu_ = oskar_mem_double(uu, &status); vv_ = oskar_mem_double(vv, &status); ww_ = oskar_mem_double(ww, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Fill station coordinates with test data. for (int i = 0; i < num_stations; ++i) { u_[i] = (double)(i + 1); v_[i] = (double)(i + 2); w_[i] = (double)(i + 3); } // Evaluate baseline coordinates on CPU. oskar_convert_station_uvw_to_baseline_uvw(num_stations, 0, u, v, w, 0, uu, vv, ww, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check results are correct. for (int s1 = 0, b = 0; s1 < num_stations; ++s1) { for (int s2 = s1 + 1; s2 < num_stations; ++s2, ++b) { EXPECT_DOUBLE_EQ(u_[s2] - u_[s1], uu_[b]); EXPECT_DOUBLE_EQ(v_[s2] - v_[s1], vv_[b]); EXPECT_DOUBLE_EQ(w_[s2] - w_[s1], ww_[b]); } } // Allocate device memory and copy input data. #ifdef OSKAR_HAVE_CUDA location = OSKAR_GPU; #endif u_gpu = oskar_mem_create_copy(u, location, &status); v_gpu = oskar_mem_create_copy(v, location, &status); w_gpu = oskar_mem_create_copy(w, location, &status); uu_gpu = oskar_mem_create(type, location, num_baselines, &status); vv_gpu = oskar_mem_create(type, location, num_baselines, &status); ww_gpu = oskar_mem_create(type, location, num_baselines, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Evaluate baseline coordinates on device. oskar_convert_station_uvw_to_baseline_uvw(num_stations, 0, u_gpu, v_gpu, w_gpu, 0, uu_gpu, vv_gpu, ww_gpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check results are consistent. double max_, avg; oskar_mem_evaluate_relative_error(uu_gpu, uu, 0, &max_, &avg, 0, &status); ASSERT_LT(max_, 1e-12); ASSERT_LT(avg, 1e-12); oskar_mem_evaluate_relative_error(vv_gpu, vv, 0, &max_, &avg, 0, &status); ASSERT_LT(max_, 1e-12); ASSERT_LT(avg, 1e-12); oskar_mem_evaluate_relative_error(ww_gpu, ww, 0, &max_, &avg, 0, &status); ASSERT_LT(max_, 1e-12); ASSERT_LT(avg, 1e-12); // Free memory. oskar_mem_free(u, &status); oskar_mem_free(v, &status); oskar_mem_free(w, &status); oskar_mem_free(uu, &status); oskar_mem_free(vv, &status); oskar_mem_free(ww, &status); oskar_mem_free(u_gpu, &status); oskar_mem_free(v_gpu, &status); oskar_mem_free(w_gpu, &status); oskar_mem_free(uu_gpu, &status); oskar_mem_free(vv_gpu, &status); oskar_mem_free(ww_gpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); }