19 #include <OpenCLTypes.hpp> 21 #include <InitializeOpenCL.hpp> 22 #include <Observation.hpp> 24 #include <Statistics.hpp> 66 std::string
print()
const;
69 bool subbandDedispersion;
70 bool conditionalReplacement;
100 using RFImConfigurations = std::map<std::string, std::map<unsigned int, std::map<float, RFImConfig *> *> *>;
113 void readSigmaSteps(
const std::string &inputFilename, std::vector<float> &steps);
129 template<
typename DataType>
130 std::uint64_t
timeDomainSigmaCut(
const bool subbandDedispersion,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const AstroData::Observation & observation, std::vector<DataType> & time_series,
const float sigmaCut,
const unsigned int padding);
145 template<
typename DataType>
160 template<
typename DataType>
179 template<
typename DataType>
180 void testTimeDomainSigmaCut(
const bool printCode,
const bool printResults,
const RFImConfig & config,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series, isa::OpenCL::OpenCLRunTime & openCLRunTime,
const unsigned int clDeviceID,
const float sigmaCut,
const unsigned int padding);
197 template<
typename DataType>
198 void tuneTimeDomainSigmaCut(
const bool subbandDedispersion,
const isa::OpenCL::TuningParameters & parameters,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series,
const unsigned int clPlatformID,
const unsigned int clDeviceID,
const float sigmaCut,
const unsigned int padding);
215 template<
typename DataType>
216 std::uint64_t
frequencyDomainSigmaCut(
const bool subbandDedispersion,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const AstroData::Observation & observation, std::vector<DataType> & time_series,
const unsigned int nrBins,
const float sigmaCut,
const unsigned int padding);
232 template<
typename DataType>
248 template<
typename DataType>
268 template<
typename DataType>
269 void testFrequencyDomainSigmaCut(
const bool printCode,
const bool printResults,
const RFImConfig & config,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series, isa::OpenCL::OpenCLRunTime & openCLRunTime,
const unsigned int clDeviceID,
const unsigned int nrBins,
const float sigmaCut,
const unsigned int padding);
287 template<
typename DataType>
288 void tuneFrequencyDomainSigmaCut(
const bool subbandDedispersion,
const isa::OpenCL::TuningParameters & parameters,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series,
const unsigned int clPlatformID,
const unsigned int clDeviceID,
const unsigned int nrBins,
const float sigmaCut,
const unsigned int padding);
294 return subbandDedispersion;
299 return conditionalReplacement;
304 subbandDedispersion = subband;
309 conditionalReplacement = replacement;
314 return std::to_string(subbandDedispersion) +
" " + std::to_string(conditionalReplacement) +
" " + isa::OpenCL::KernelConf::print();
317 template<
typename DataType>
320 std::uint64_t replacedSamples = 0;
321 for (
unsigned int beam = 0; beam < observation.getNrBeams(); beam++ )
325 for (
unsigned int channel = 0; channel < observation.getNrChannels(); channel++ )
327 isa::utils::Statistics<DataType> statistics;
328 for (
unsigned int sample_id = 0; sample_id < observation.getNrSamplesPerDispersedBatch(subbandDedispersion); sample_id++ )
330 statistics.addElement(time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + sample_id));
332 for (
unsigned int sample_id = 0; sample_id < observation.getNrSamplesPerDispersedBatch(subbandDedispersion); sample_id++ )
334 DataType sample_value = time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + sample_id);
335 if ( sample_value > (statistics.getMean() + (sigmaCut * statistics.getStandardDeviation())) )
340 time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + sample_id) =
static_cast<DataType
>(statistics.getMean());
347 return replacedSamples;
350 template<
typename DataType>
355 return getTimeDomainSigmaCutOpenCL_FrequencyTime_ReplaceWithMean<DataType>(config, dataTypeName, observation, sigmaCut, padding);
357 return new std::string();
360 template<
typename DataType>
363 std::string *code =
new std::string();
365 *code =
"__kernel void timeDomainSigmaCut(__global " + dataTypeName +
" * const restrict time_series) {\n" 366 + config.getIntType() +
" threshold = 0;\n" 367 "float delta = 0.0f;\n" 368 "float mean = 0.0f;\n" 369 "float sigma_cut = 0.0f;\n" 370 + dataTypeName +
" sample_value;\n" 371 "__local float reductionCOU[" + std::to_string(config.getNrThreadsD0()) +
"];\n" 372 "__local float reductionMEA[" + std::to_string(config.getNrThreadsD0()) +
"];\n" 373 "__local float reductionVAR[" + std::to_string(config.getNrThreadsD0()) +
"];\n" 374 "<%LOCAL_VARIABLES%>" 376 "// Compute mean and standard deviation\n" 377 "for ( " + config.getIntType() +
" sample_id = get_local_id(0) + " + std::to_string(config.getNrThreadsD0() * config.getNrItemsD0()) +
"; sample_id < " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion())) +
"; sample_id += " + std::to_string(config.getNrThreadsD0() * config.getNrItemsD0()) +
" ) " 381 "// Local reduction (if necessary)\n" 383 "reductionCOU[get_local_id(0)] = counter_0;\n" 384 "reductionMEA[get_local_id(0)] = mean_0;\n" 385 "reductionVAR[get_local_id(0)] = variance_0;\n" 386 "barrier(CLK_LOCAL_MEM_FENCE);\n" 387 "// Global reduction\n" 388 "threshold = " + std::to_string(config.getNrThreadsD0() / 2) +
";\n" 389 "for (" + config.getIntType() +
" sample_id = get_local_id(0); threshold > 0; threshold /= 2 ) {\n" 390 "if ( (sample_id < threshold)) {\n" 391 "delta = reductionMEA[sample_id + threshold] - mean_0;\n" 392 "counter_0 += reductionCOU[sample_id + threshold];\n" 393 "mean_0 = ((reductionCOU[sample_id] * mean_0) + (reductionCOU[sample_id + threshold] * reductionMEA[sample_id + threshold])) / counter_0;\n" 394 "variance_0 += reductionVAR[sample_id + threshold] + ((delta * delta) * ((reductionCOU[sample_id] * reductionCOU[sample_id + threshold]) / counter_0));\n" 395 "reductionCOU[sample_id] = counter_0;\n" 396 "reductionMEA[sample_id] = mean_0;\n" 397 "reductionVAR[sample_id] = variance_0;\n" 399 "barrier(CLK_LOCAL_MEM_FENCE);\n" 401 "mean = reductionMEA[0];\n" 402 "sigma_cut = (" + std::to_string(sigmaCut) +
" * native_sqrt(reductionVAR[0] * " + std::to_string(1.0f/(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion()) - 1)) +
"f));\n" 403 "// Replace samples over the sigma cut with mean\n" 404 "for (" + config.getIntType() +
" sample_id = get_local_id(0); sample_id < " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion())) +
"; sample_id += " + std::to_string(config.getNrThreadsD0() * config.getNrItemsD0()) +
" ) " 410 std::string localVariablesTemplate =
"float counter_<%ITEM_NUMBER%> = 1.0f;\n" 411 "float variance_<%ITEM_NUMBER%> = 0.0f;\n" 412 "float mean_<%ITEM_NUMBER%> = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + get_local_id(0) + <%ITEM_OFFSET%>];\n";
415 std::string localComputeNoCheckTemplate =
"sample_value = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + get_local_id(0) + <%ITEM_OFFSET%>];\n" 416 "counter_<%ITEM_NUMBER%> += 1.0f;\n" 417 "delta = sample_value - mean_<%ITEM_NUMBER%>;\n" 418 "mean_<%ITEM_NUMBER%> += delta / counter_<%ITEM_NUMBER%>;\n" 419 "variance_<%ITEM_NUMBER%> += delta * (sample_value - mean_<%ITEM_NUMBER%>);\n";
421 std::string localComputeCheckTemplate =
"if ( sample_id + <%ITEM_OFFSET%> < " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion())) +
" ) {\n" 422 "sample_value = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + get_local_id(0) + <%ITEM_OFFSET%>];\n" 423 "counter_<%ITEM_NUMBER%> += 1.0f;\n" 424 "delta = sample_value - mean_<%ITEM_NUMBER%>;\n" 425 "mean_<%ITEM_NUMBER%> += delta / counter_<%ITEM_NUMBER%>;\n" 426 "variance_<%ITEM_NUMBER%> += delta * (sample_value - mean_<%ITEM_NUMBER%>);\n" 429 std::string localReduceTemplate =
"delta = mean_<%ITEM_NUMBER%> - mean_0;\n" 430 "counter_0 += counter_<%ITEM_NUMBER%>;\n" 431 "mean_0 = (((counter_0 - counter_<%ITEM_NUMBER%>) * mean_0) + (counter_<%ITEM_NUMBER%> * mean_<%ITEM_NUMBER%>)) / counter_0;\n" 432 "variance_0 += variance_<%ITEM_NUMBER%> + ((delta * delta) * (((counter_0 - counter_<%ITEM_NUMBER%>) * counter_<%ITEM_NUMBER%>) / counter_0));\n";
433 std::string replaceConditionTemplate =
"if ( time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + sample_id + <%ITEM_OFFSET%>] > (mean + sigma_cut) ) {\n";
434 if (
typeid(DataType) ==
typeid(float) )
436 replaceConditionTemplate +=
"time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + sample_id + <%ITEM_OFFSET%>] = mean;\n";
440 replaceConditionTemplate +=
"time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + sample_id + <%ITEM_OFFSET%>] = convert_" + dataTypeName +
"(mean);\n";
442 replaceConditionTemplate +=
"}\n";
443 std::string replaceTemplate =
"sample_value = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + sample_id + <%ITEM_OFFSET%>];\n" 444 "time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_global_id(1) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + sample_id + <%ITEM_OFFSET%>] = (sample_value * (convert_" + dataTypeName +
"(sample_value < (mean + sigma_cut)))) + (mean * (convert_" + dataTypeName +
"(sample_value > mean + sigma_cut)));\n";
447 std::string localVariables;
448 std::string localCompute;
449 std::string localReduce;
451 for (
unsigned int item = 0; item < config.getNrItemsD0(); item++ )
454 std::string itemString = std::to_string(item);
455 std::string itemOffsetString = std::to_string(item * config.getNrThreadsD0());
456 temp = isa::utils::replace(&localVariablesTemplate,
"<%ITEM_NUMBER%>", itemString);
459 temp = isa::utils::replace(temp,
" + <%ITEM_OFFSET%>", std::string(),
true);
463 temp = isa::utils::replace(temp,
"<%ITEM_OFFSET%>", itemOffsetString,
true);
465 localVariables.append(*temp);
467 if ( (observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion()) % (config.getNrThreadsD0() * config.getNrItemsD0())) == 0 )
469 temp = isa::utils::replace(&localComputeNoCheckTemplate,
"<%ITEM_NUMBER%>", itemString);
473 temp = isa::utils::replace(&localComputeCheckTemplate,
"<%ITEM_NUMBER%>", itemString);
477 temp = isa::utils::replace(temp,
" + <%ITEM_OFFSET%>", std::string(),
true);
481 temp = isa::utils::replace(temp,
"<%ITEM_OFFSET%>", itemOffsetString,
true);
483 localCompute.append(*temp);
487 temp = isa::utils::replace(&localReduceTemplate,
"<%ITEM_NUMBER%>", itemString);
488 localReduce.append(*temp);
493 temp = isa::utils::replace(&replaceConditionTemplate,
"<%ITEM_NUMBER%>", itemString);
497 temp = isa::utils::replace(&replaceTemplate,
"<%ITEM_NUMBER%>", itemString);
501 temp = isa::utils::replace(temp,
" + <%ITEM_OFFSET%>", std::string(),
true);
505 temp = isa::utils::replace(temp,
"<%ITEM_OFFSET%>", itemOffsetString,
true);
507 replace.append(*temp);
509 code = isa::utils::replace(code,
"<%LOCAL_VARIABLES%>", localVariables,
true);
510 code = isa::utils::replace(code,
"<%LOCAL_COMPUTE%>", localCompute,
true);
511 code = isa::utils::replace(code,
"<%LOCAL_REDUCE%>", localReduce,
true);
512 code = isa::utils::replace(code,
"<%REPLACE%>", replace,
true);
516 template<
typename DataType>
517 void RFIm::testTimeDomainSigmaCut(
const bool printCode,
const bool printResults,
const RFImConfig & config,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series, isa::OpenCL::OpenCLRunTime & openCLRunTime,
const unsigned int clDeviceID,
const float sigmaCut,
const unsigned int padding)
519 std::uint64_t wrongSamples = 0;
520 std::uint64_t replacedSamples = 0;
521 std::vector<DataType> test_time_series, control_time_series;
522 test_time_series = time_series;
523 control_time_series = time_series;
524 cl::Buffer device_time_series;
525 cl::Kernel * kernel =
nullptr;
527 std::string * code = getTimeDomainSigmaCutOpenCL<DataType>(config, ordering, replacement, dataTypeName, observation, sigmaCut, padding);
530 std::cout << std::endl;
531 std::cout << *code << std::endl;
532 std::cout << std::endl;
537 replacedSamples =
timeDomainSigmaCut(config.getSubbandDedispersion(), ordering, replacement, observation, control_time_series, sigmaCut, padding);
541 device_time_series = cl::Buffer(*(openCLRunTime.context), CL_MEM_READ_WRITE, test_time_series.size() *
sizeof(DataType), 0, 0);
543 catch (
const cl::Error & err )
545 std::cerr <<
"OpenCL device memory allocation error: " << std::to_string(err.err()) <<
"." << std::endl;
550 openCLRunTime.queues->at(clDeviceID)[0].enqueueWriteBuffer(device_time_series, CL_FALSE, 0, test_time_series.size() *
sizeof(DataType), reinterpret_cast<void *>(test_time_series.data()));
552 catch(
const cl::Error & err )
554 std::cerr <<
"OpenCL transfer H2D error: " << std::to_string(err.err()) <<
"." << std::endl;
558 kernel = isa::OpenCL::compile(
"timeDomainSigmaCut", *code,
"-cl-mad-enable -Werror", *(openCLRunTime.context), openCLRunTime.devices->at(clDeviceID));
560 catch (
const isa::OpenCL::OpenCLError & err )
562 std::cerr << err.what() << std::endl;
568 cl::NDRange global, local;
569 global = cl::NDRange(config.getNrThreadsD0(), observation.getNrChannels(), observation.getNrBeams());
570 local = cl::NDRange(config.getNrThreadsD0(), 1, 1);
571 kernel->setArg(0, device_time_series);
572 openCLRunTime.queues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local);
573 openCLRunTime.queues->at(clDeviceID)[0].enqueueReadBuffer(device_time_series, CL_TRUE, 0, test_time_series.size() *
sizeof(DataType), reinterpret_cast<void *>(test_time_series.data()));
575 catch (
const cl::Error & err )
577 std::cerr <<
"OpenCL kernel execution error: " << std::to_string(err.err()) <<
"." << std::endl;
582 for (
unsigned int beam = 0; beam < observation.getNrBeams(); beam++ )
586 for (
unsigned int channel = 0; channel < observation.getNrChannels(); channel++ )
588 for (
unsigned int sample_id = 0; sample_id < observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion()); sample_id++ )
590 if ( !isa::utils::same<double>(test_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id), control_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id), 1.1) )
596 std::cout << static_cast<double>(test_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id)) <<
" " << static_cast<double>(control_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id)) <<
" ; ";
601 std::cout << std::endl;
607 if ( wrongSamples > 0 )
609 std::cout << std::fixed;
610 std::cout <<
"Wrong samples: " << wrongSamples <<
" (" << (wrongSamples * 100.0) / (
static_cast<std::uint64_t
>(observation.getNrBeams()) * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion())) <<
"%)." << std::endl;
614 std::cout <<
"TEST PASSED." << std::endl;
618 template<
typename DataType>
619 void RFIm::tuneTimeDomainSigmaCut(
const bool subbandDedispersion,
const isa::OpenCL::TuningParameters & parameters,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series,
const unsigned int clPlatformID,
const unsigned int clDeviceID,
const float sigmaCut,
const unsigned int padding)
621 bool initializeDevice =
true;
622 isa::utils::Timer timer;
623 double bestTime = std::numeric_limits<double>::max();
625 std::vector<RFImConfig> configurations;
626 isa::OpenCL::OpenCLRunTime openCLRunTime;
628 cl::Buffer device_time_series;
630 for (
unsigned int threads = parameters.getMinThreads(); threads <= parameters.getMaxThreads(); threads *= 2 )
632 for (
unsigned int items = 1; (items * 3) + 8 <= parameters.getMaxItems(); items++ )
634 if ( (threads * items) > observation.getNrSamplesPerDispersedBatch(subbandDedispersion) )
640 baseConfig.setNrThreadsD0(threads);
641 baseConfig.setNrItemsD0(items);
643 tempConfig = baseConfig;
645 tempConfig.setIntType(0);
646 configurations.push_back(tempConfig);
648 tempConfig = baseConfig;
650 tempConfig.setIntType(1);
651 configurations.push_back(tempConfig);
653 tempConfig = baseConfig;
655 tempConfig.setIntType(0);
656 configurations.push_back(tempConfig);
658 tempConfig = baseConfig;
660 tempConfig.setIntType(1);
661 configurations.push_back(tempConfig);
665 std::cout << std::fixed;
666 if ( !parameters.getBestMode() )
668 std::cout << std::endl <<
"# nrBeams nrChannels nrSamplesPerDispersedBatch sigma *configuration* time stdDeviation COV" << std::endl << std::endl;
670 for (
auto configuration = configurations.begin(); configuration != configurations.end(); ++configuration )
672 cl::Kernel * kernel =
nullptr;
674 std::string * code = getTimeDomainSigmaCutOpenCL<DataType>(*configuration, ordering, replacement, dataTypeName, observation, sigmaCut, padding);
675 if ( initializeDevice )
677 isa::OpenCL::initializeOpenCL(clPlatformID, 1, openCLRunTime);
680 device_time_series = cl::Buffer(*(openCLRunTime.context), CL_MEM_READ_WRITE, time_series.size() *
sizeof(DataType), 0, 0);
682 catch (
const cl::Error & err )
684 std::cerr <<
"OpenCL device memory allocation error: " << std::to_string(err.err()) <<
"." << std::endl;
687 initializeDevice =
false;
691 kernel = isa::OpenCL::compile(
"timeDomainSigmaCut", *code,
"-cl-mad-enable -Werror", *(openCLRunTime.context), openCLRunTime.devices->at(clDeviceID));
693 catch (
const isa::OpenCL::OpenCLError & err )
695 std::cerr << err.what() << std::endl;
701 cl::NDRange global, local;
702 global = cl::NDRange((*configuration).getNrThreadsD0(), observation.getNrChannels(), observation.getNrBeams());
703 local = cl::NDRange((*configuration).getNrThreadsD0(), 1, 1);
704 kernel->setArg(0, device_time_series);
706 openCLRunTime.queues->at(clDeviceID)[0].enqueueWriteBuffer(device_time_series, CL_FALSE, 0, time_series.size() *
sizeof(DataType), reinterpret_cast<const void *>(time_series.data()),
nullptr, &clEvent);
708 openCLRunTime.queues->at(clDeviceID)[0].finish();
709 openCLRunTime.queues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local,
nullptr, &clEvent);
712 for (
unsigned int iteration = 0; iteration < parameters.getNrIterations(); iteration++ )
714 openCLRunTime.queues->at(clDeviceID)[0].enqueueWriteBuffer(device_time_series, CL_FALSE, 0, time_series.size() *
sizeof(DataType), reinterpret_cast<const void *>(time_series.data()),
nullptr, &clEvent);
716 openCLRunTime.queues->at(clDeviceID)[0].finish();
718 openCLRunTime.queues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local,
nullptr, &clEvent);
723 catch (
const cl::Error & err )
725 std::cerr <<
"OpenCL kernel error during tuning: " << std::to_string(err.err()) <<
"." << std::endl;
727 if (err.err() == -4 || err.err() == -61)
731 initializeDevice =
true;
735 if ( timer.getAverageTime() < bestTime )
737 bestTime = timer.getAverageTime();
738 bestConfig = *configuration;
740 if ( !parameters.getBestMode() )
742 std::cout << observation.getNrBeams() <<
" " << observation.getNrChannels() <<
" ";
743 std::cout << observation.getNrSamplesPerDispersedBatch(subbandDedispersion) <<
" ";
744 std::cout.precision(2);
745 std::cout << sigmaCut <<
" ";
746 std::cout << (*configuration).
print() <<
" ";
747 std::cout.precision(6);
748 std::cout << timer.getAverageTime() <<
" " << timer.getStandardDeviation() <<
" " << timer.getCoefficientOfVariation();
749 std::cout << std::endl;
753 if ( parameters.getBestMode() )
755 std::cout.precision(2);
756 std::cout << observation.getNrSamplesPerDispersedBatch(subbandDedispersion) <<
" " << sigmaCut <<
" ";
757 std::cout << bestConfig.
print() << std::endl;
761 std::cout << std::endl;
765 template<
typename DataType>
768 std::uint64_t replacedSamples = 0;
769 unsigned int nrChannelsPerBin =
static_cast<unsigned int>(std::ceil(observation.getNrChannels() / nrBins));
770 for (
unsigned int beam = 0; beam < observation.getNrBeams(); beam++ )
774 for (
unsigned int sample_id = 0; sample_id < observation.getNrSamplesPerDispersedBatch(subbandDedispersion); sample_id++ )
776 isa::utils::Statistics<DataType> statistics_corrected;
777 isa::utils::Statistics<DataType> * local_statistics =
new isa::utils::Statistics<DataType> [nrBins];
780 for (
unsigned int channel = 0; channel < observation.getNrChannels(); channel++ )
782 local_statistics[channel / nrChannelsPerBin].addElement(time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + sample_id));
786 for (
unsigned int channel = 0; channel < observation.getNrChannels(); channel++ )
788 statistics_corrected.addElement(time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + sample_id) - local_statistics[channel / nrChannelsPerBin].getMean());
792 for (
unsigned int channel = 0; channel < observation.getNrChannels(); channel++ )
794 DataType sample_value = time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + sample_id) - local_statistics[channel / nrChannelsPerBin].getMean();
795 if ( sample_value > statistics_corrected.getMean() + (sigmaCut * statistics_corrected.getStandardDeviation()) )
800 time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(subbandDedispersion, padding /
sizeof(DataType))) + sample_id) =
static_cast<DataType
>(local_statistics[channel / nrChannelsPerBin].getMean());
804 delete [] local_statistics;
808 return replacedSamples;
811 template<
typename DataType>
816 return getFrequencyDomainSigmaCutOpenCL_FrequencyTime_ReplaceWithMean<DataType>(config, dataTypeName, observation, nrBins, sigmaCut, padding);
818 return new std::string();
821 template<
typename DataType>
824 unsigned int binSize = observation.getNrChannels() / nrBins;
825 std::string *code =
new std::string();
827 *code =
"__kernel void frequencyDomainSigmaCut(__global " + dataTypeName +
" * const restrict time_series) {\n" 828 "float delta = 0.0f;\n" 829 "float sigma_cut = 0.0f;\n" 830 + dataTypeName +
" sample_value;\n" 831 "<%LOCAL_VARIABLES%>" 834 "// Stop unnecessary threads\n" 835 "if ( ((get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + get_local_id(0)) >= " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion())) +
" )\n" 839 "// Compute mean for each bin\n" 840 "<%COMPUTE_MEAN_BIN%>" 841 "// Compute mean and standard deviation corrected for local bin\n" 843 "// Local reduction (if necessary)\n" 845 "sigma_cut = (" + std::to_string(sigmaCut) +
" * native_sqrt(variance_0 * " + std::to_string(1.0f/(observation.getNrChannels() - 1)) +
"f));\n" 846 "// Replace samples over the sigma cut with mean\n" 850 std::string localVariablesTemplate =
"float counter_<%ITEM_NUMBER%> = 1.0f;\n" 851 "float variance_<%ITEM_NUMBER%> = 0.0f;\n" 852 "float mean_<%ITEM_NUMBER%> = 0.0f;\n";
853 std::string binVariablesTemplate =
"float mean_bin_<%BIN_NUMBER%> = 0.0f;\n";
855 std::string binComputeMeanTemplate =
"mean_bin_<%BIN_NUMBER%> = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((<%BIN_NUMBER%> * " + std::to_string(binSize) +
") * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + get_local_id(0)];\n" 856 "for ( " + config.getIntType() +
" channel_id = (<%BIN_NUMBER%> * " + std::to_string(binSize) +
") + 1; channel_id < (<%BIN_NUMBER%> + 1) * " + std::to_string(binSize) +
"; channel_id++ )\n" 858 "mean_bin_<%BIN_NUMBER%> += time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (channel_id * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)];\n" 860 "mean_bin_<%BIN_NUMBER%> /= " + std::to_string(binSize) +
";\n";
863 std::string localComputeNoCheckTemplate =
"for ( " + config.getIntType() +
" channel_id = ((<%BIN_NUMBER%> * " + std::to_string(binSize) +
") + <%ITEM_NUMBER%>); channel_id < (<%BIN_NUMBER%> + 1) * " + std::to_string(binSize) +
"; channel_id += " + std::to_string(config.getNrItemsD1()) +
" )\n" 865 "sample_value = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((channel_id + <%ITEM_NUMBER%>) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)] - mean_bin_<%BIN_NUMBER%>;\n" 866 "counter_<%ITEM_NUMBER%> += 1.0f;\n" 867 "delta = sample_value - mean_<%ITEM_NUMBER%>;\n" 868 "mean_<%ITEM_NUMBER%> += delta / counter_<%ITEM_NUMBER%>;\n" 869 "variance_<%ITEM_NUMBER%> += delta * (sample_value - mean_<%ITEM_NUMBER%>);\n" 872 std::string localComputeCheckTemplate =
"for ( " + config.getIntType() +
" channel_id = ((<%BIN_NUMBER%> * " + std::to_string(binSize) +
") + <%ITEM_NUMBER%>); channel_id < (<%BIN_NUMBER%> + 1) * " + std::to_string(binSize) +
"; channel_id += " + std::to_string(config.getNrItemsD1()) +
" )\n" 874 "if ( channel_id + <%ITEM_NUMBER%> < " + std::to_string(binSize) +
" ) {\n" 875 "sample_value = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((channel_id + <%ITEM_NUMBER%>) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)] - mean_bin_<%BIN_NUMBER%>;\n" 876 "counter_<%ITEM_NUMBER%> += 1.0f;\n" 877 "delta = sample_value - mean_<%ITEM_NUMBER%>;\n" 878 "mean_<%ITEM_NUMBER%> += delta / counter_<%ITEM_NUMBER%>;\n" 879 "variance_<%ITEM_NUMBER%> += delta * (sample_value - mean_<%ITEM_NUMBER%>);\n" 883 std::string localReduceTemplate =
"delta = mean_<%ITEM_NUMBER%> - mean_0;\n" 884 "counter_0 += counter_<%ITEM_NUMBER%>;\n" 885 "mean_0 = (((counter_0 - counter_<%ITEM_NUMBER%>) * mean_0) + (counter_<%ITEM_NUMBER%> * mean_<%ITEM_NUMBER%>)) / counter_0;\n" 886 "variance_0 += variance_<%ITEM_NUMBER%> + ((delta * delta) * (((counter_0 - counter_<%ITEM_NUMBER%>) * counter_<%ITEM_NUMBER%>) / counter_0));\n";
888 std::string replaceConditionTemplate =
"for ( " + config.getIntType() +
" channel_id = ((<%BIN_NUMBER%> * " + std::to_string(binSize) +
") + <%ITEM_NUMBER%>); channel_id < (<%BIN_NUMBER%> + 1) * " + std::to_string(binSize) +
"; channel_id += " + std::to_string(config.getNrItemsD1()) +
" )\n" 890 "if ( (time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((channel_id + <%ITEM_NUMBER%>) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)] - mean_bin_<%BIN_NUMBER%>) > (mean_0 + sigma_cut) ) {\n";
891 if (
typeid(DataType) ==
typeid(float) )
893 replaceConditionTemplate +=
"time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((channel_id + <%ITEM_NUMBER%>) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)] = mean_bin_<%BIN_NUMBER%>;\n";
897 replaceConditionTemplate +=
"time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((channel_id + <%ITEM_NUMBER%>) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)] = convert_" + dataTypeName +
"(mean_bin_<%BIN_NUMBER%>);\n";
899 replaceConditionTemplate +=
"}\n" 902 std::string replaceTemplate =
"for ( " + config.getIntType() +
" channel_id = ((<%BIN_NUMBER%> * " + std::to_string(binSize) +
") + <%ITEM_NUMBER%>); channel_id < (<%BIN_NUMBER%> + 1) * " + std::to_string(binSize) +
"; channel_id += " + std::to_string(config.getNrItemsD1()) +
" )\n" 904 "sample_value = time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((channel_id + <%ITEM_NUMBER%>) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)];\n" 905 "time_series[(get_global_id(2) * " + std::to_string(observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + ((channel_id + <%ITEM_NUMBER%>) * " + std::to_string(observation.getNrSamplesPerDispersedBatch(config.
getSubbandDedispersion(), padding /
sizeof(DataType))) +
") + (get_group_id(0) * " + std::to_string(config.getNrThreadsD0()) +
") + (channel_id + <%ITEM_NUMBER%>)] = ((sample_value) * (convert_" + dataTypeName +
"( (sample_value - mean_bin_<%BIN_NUMBER%>) <= (mean_0 + sigma_cut) ))) + (mean_bin_<%BIN_NUMBER%> * (convert_" + dataTypeName +
"( (sample_value - mean_bin_<%BIN_NUMBER%>) > (mean_0 + sigma_cut) )));\n" 909 std::string localVariables;
910 std::string binVariables;
911 std::string binComputeMean;
912 std::string localCompute;
913 std::string localReduce;
915 for (
unsigned int item = 0; item < config.getNrItemsD1(); item++ )
918 std::string itemString = std::to_string(item);
919 temp = isa::utils::replace(&localVariablesTemplate,
"<%ITEM_NUMBER%>", itemString);
920 localVariables.append(*temp);
924 temp = isa::utils::replace(&localReduceTemplate,
"<%ITEM_NUMBER%>", itemString);
925 localReduce.append(*temp);
929 for (
unsigned int bin = 0; bin < nrBins; bin++ )
932 std::string binString = std::to_string(bin);
933 temp = isa::utils::replace(&binVariablesTemplate,
"<%BIN_NUMBER%>", binString);
934 binVariables.append(*temp);
936 for (
unsigned int item = 0; item < config.getNrItemsD1(); item++ )
938 std::string itemString = std::to_string(item);
940 temp = isa::utils::replace(&binComputeMeanTemplate,
"<%ITEM_NUMBER%>", itemString);
943 temp = isa::utils::replace(temp,
" + 0", std::string(),
true);
945 temp = isa::utils::replace(temp,
"<%BIN_NUMBER%>", binString,
true);
946 binComputeMean.append(*temp);
949 if ( (binSize % config.getNrItemsD1()) == 0 )
951 temp = isa::utils::replace(&localComputeNoCheckTemplate,
"<%ITEM_NUMBER%>", itemString);
955 temp = isa::utils::replace(&localComputeCheckTemplate,
"<%ITEM_NUMBER%>", itemString);
959 temp = isa::utils::replace(temp,
" + 0", std::string(),
true);
961 temp = isa::utils::replace(temp,
"<%BIN_NUMBER%>", binString,
true);
962 localCompute.append(*temp);
966 temp = isa::utils::replace(&replaceConditionTemplate,
"<%ITEM_NUMBER%>", itemString);
970 temp = isa::utils::replace(&replaceTemplate,
"<%ITEM_NUMBER%>", itemString);
974 temp = isa::utils::replace(temp,
" + 0", std::string(),
true);
976 temp = isa::utils::replace(temp,
"<%BIN_NUMBER%>", binString,
true);
977 replace.append(*temp);
980 code = isa::utils::replace(code,
"<%LOCAL_VARIABLES%>", localVariables,
true);
981 code = isa::utils::replace(code,
"<%BIN_VARIABLES%>", binVariables,
true);
982 code = isa::utils::replace(code,
"<%COMPUTE_MEAN_BIN%>", binComputeMean,
true);
983 code = isa::utils::replace(code,
"<%LOCAL_COMPUTE%>", localCompute,
true);
984 code = isa::utils::replace(code,
"<%LOCAL_REDUCE%>", localReduce,
true);
985 code = isa::utils::replace(code,
"<%REPLACE%>", replace,
true);
989 template<
typename DataType>
990 void RFIm::testFrequencyDomainSigmaCut(
const bool printCode,
const bool printResults,
const RFImConfig & config,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series, isa::OpenCL::OpenCLRunTime & openCLRunTime,
const unsigned int clDeviceID,
const unsigned int nrBins,
const float sigmaCut,
const unsigned int padding)
992 std::uint64_t wrongSamples = 0;
993 std::uint64_t replacedSamples = 0;
994 std::vector<DataType> test_time_series, control_time_series;
995 test_time_series = time_series;
996 control_time_series = time_series;
997 cl::Buffer device_time_series;
998 cl::Kernel * kernel =
nullptr;
1000 std::string * code = getFrequencyDomainSigmaCutOpenCL<DataType>(config, ordering, replacement, dataTypeName, observation, nrBins, sigmaCut, padding);
1003 std::cout << std::endl;
1004 std::cout << *code << std::endl;
1005 std::cout << std::endl;
1010 replacedSamples =
frequencyDomainSigmaCut(config.getSubbandDedispersion(), ordering, replacement, observation, control_time_series, nrBins, sigmaCut, padding);
1014 device_time_series = cl::Buffer(*(openCLRunTime.context), CL_MEM_READ_WRITE, test_time_series.size() *
sizeof(DataType), 0, 0);
1016 catch (
const cl::Error & err )
1018 std::cerr <<
"OpenCL device memory allocation error: " << std::to_string(err.err()) <<
"." << std::endl;
1023 openCLRunTime.queues->at(clDeviceID)[0].enqueueWriteBuffer(device_time_series, CL_FALSE, 0, test_time_series.size() *
sizeof(DataType), reinterpret_cast<void *>(test_time_series.data()));
1025 catch(
const cl::Error & err )
1027 std::cerr <<
"OpenCL transfer H2D error: " << std::to_string(err.err()) <<
"." << std::endl;
1031 kernel = isa::OpenCL::compile(
"frequencyDomainSigmaCut", *code,
"-cl-mad-enable -Werror", *(openCLRunTime.context), openCLRunTime.devices->at(clDeviceID));
1033 catch (
const isa::OpenCL::OpenCLError & err )
1035 std::cerr << err.what() << std::endl;
1041 cl::NDRange global, local;
1042 global = cl::NDRange(isa::utils::pad(observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion()), config.getNrThreadsD0()), 1, observation.getNrBeams());
1043 local = cl::NDRange(config.getNrThreadsD0(), 1, 1);
1044 kernel->setArg(0, device_time_series);
1045 openCLRunTime.queues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local);
1046 openCLRunTime.queues->at(clDeviceID)[0].enqueueReadBuffer(device_time_series, CL_TRUE, 0, test_time_series.size() *
sizeof(DataType), reinterpret_cast<void *>(test_time_series.data()));
1048 catch (
const cl::Error & err )
1050 std::cerr <<
"OpenCL kernel execution error: " << std::to_string(err.err()) <<
"." << std::endl;
1055 for (
unsigned int beam = 0; beam < observation.getNrBeams(); beam++ )
1059 for (
unsigned int channel = 0; channel < observation.getNrChannels(); channel++ )
1061 for (
unsigned int sample_id = 0; sample_id < observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion()); sample_id++ )
1063 if ( !isa::utils::same<double>(test_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id), control_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id), 1.1) )
1069 std::cout << static_cast<double>(test_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id)) <<
" " << static_cast<double>(control_time_series.at((beam * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + (channel * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion(), padding /
sizeof(DataType))) + sample_id)) <<
" ; ";
1074 std::cout << std::endl;
1080 if ( wrongSamples > 0 )
1082 std::cout << std::fixed;
1083 std::cout <<
"Wrong samples: " << wrongSamples <<
" (" << (wrongSamples * 100.0) / (
static_cast<std::uint64_t
>(observation.getNrBeams()) * observation.getNrChannels() * observation.getNrSamplesPerDispersedBatch(config.getSubbandDedispersion())) <<
"%)." << std::endl;
1087 std::cout <<
"TEST PASSED." << std::endl;
1091 template<
typename DataType>
1092 void RFIm::tuneFrequencyDomainSigmaCut(
const bool subbandDedispersion,
const isa::OpenCL::TuningParameters & parameters,
const DataOrdering & ordering,
const ReplacementStrategy & replacement,
const std::string & dataTypeName,
const AstroData::Observation & observation,
const std::vector<DataType> & time_series,
const unsigned int clPlatformID,
const unsigned int clDeviceID,
const unsigned int nrBins,
const float sigmaCut,
const unsigned int padding)
1094 bool initializeDevice =
true;
1095 isa::utils::Timer timer;
1096 double bestTime = std::numeric_limits<double>::max();
1098 std::vector<RFImConfig> configurations;
1099 isa::OpenCL::OpenCLRunTime openCLRunTime;
1101 cl::Buffer device_time_series;
1103 for (
unsigned int threads = parameters.getMinThreads(); threads <= parameters.getMaxThreads(); threads *= 2 )
1105 for (
unsigned int items = 1; (items * 3) + 3 + nrBins <= parameters.getMaxItems(); items++ )
1107 if ( threads > observation.getNrSamplesPerDispersedBatch(subbandDedispersion) )
1111 if ( items > (observation.getNrChannels() / nrBins) )
1117 baseConfig.setNrThreadsD0(threads);
1118 baseConfig.setNrItemsD1(items);
1120 tempConfig = baseConfig;
1122 tempConfig.setIntType(0);
1123 configurations.push_back(tempConfig);
1125 tempConfig = baseConfig;
1127 tempConfig.setIntType(1);
1128 configurations.push_back(tempConfig);
1130 tempConfig = baseConfig;
1132 tempConfig.setIntType(0);
1133 configurations.push_back(tempConfig);
1135 tempConfig = baseConfig;
1137 tempConfig.setIntType(1);
1138 configurations.push_back(tempConfig);
1142 std::cout << std::fixed;
1143 if ( !parameters.getBestMode() )
1145 std::cout << std::endl <<
"# nrBeams nrChannels nrSamplesPerDispersedBatch sigma *configuration* time stdDeviation COV" << std::endl << std::endl;
1147 for (
auto configuration = configurations.begin(); configuration != configurations.end(); ++configuration )
1149 cl::Kernel * kernel =
nullptr;
1151 std::string * code = getFrequencyDomainSigmaCutOpenCL<DataType>(*configuration, ordering, replacement, dataTypeName, observation, nrBins, sigmaCut, padding);
1152 if ( initializeDevice )
1154 isa::OpenCL::initializeOpenCL(clPlatformID, 1, openCLRunTime);
1157 device_time_series = cl::Buffer(*(openCLRunTime.context), CL_MEM_READ_WRITE, time_series.size() *
sizeof(DataType), 0, 0);
1159 catch (
const cl::Error & err )
1161 std::cerr <<
"OpenCL device memory allocation error: " << std::to_string(err.err()) <<
"." << std::endl;
1164 initializeDevice =
false;
1168 kernel = isa::OpenCL::compile(
"frequencyDomainSigmaCut", *code,
"-cl-mad-enable -Werror", *(openCLRunTime.context), openCLRunTime.devices->at(clDeviceID));
1170 catch (
const isa::OpenCL::OpenCLError & err )
1172 std::cerr << err.what() << std::endl;
1178 cl::NDRange global, local;
1179 global = cl::NDRange(isa::utils::pad(observation.getNrSamplesPerDispersedBatch(subbandDedispersion), (*configuration).getNrThreadsD0()), 1, observation.getNrBeams());
1180 local = cl::NDRange((*configuration).getNrThreadsD0(), 1, 1);
1181 kernel->setArg(0, device_time_series);
1183 openCLRunTime.queues->at(clDeviceID)[0].enqueueWriteBuffer(device_time_series, CL_FALSE, 0, time_series.size() *
sizeof(DataType), reinterpret_cast<const void *>(time_series.data()),
nullptr, &clEvent);
1185 openCLRunTime.queues->at(clDeviceID)[0].finish();
1186 openCLRunTime.queues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local,
nullptr, &clEvent);
1189 for (
unsigned int iteration = 0; iteration < parameters.getNrIterations(); iteration++ )
1191 openCLRunTime.queues->at(clDeviceID)[0].enqueueWriteBuffer(device_time_series, CL_FALSE, 0, time_series.size() *
sizeof(DataType), reinterpret_cast<const void *>(time_series.data()),
nullptr, &clEvent);
1193 openCLRunTime.queues->at(clDeviceID)[0].finish();
1195 openCLRunTime.queues->at(clDeviceID)[0].enqueueNDRangeKernel(*kernel, cl::NullRange, global, local,
nullptr, &clEvent);
1200 catch (
const cl::Error & err )
1202 std::cerr <<
"OpenCL kernel error during tuning: " << std::to_string(err.err()) <<
"." << std::endl;
1204 if (err.err() == -4 || err.err() == -61)
1208 initializeDevice =
true;
1212 if ( timer.getAverageTime() < bestTime )
1214 bestTime = timer.getAverageTime();
1215 bestConfig = *configuration;
1217 if ( !parameters.getBestMode() )
1219 std::cout << observation.getNrBeams() <<
" " << observation.getNrChannels() <<
" ";
1220 std::cout << observation.getNrSamplesPerDispersedBatch(subbandDedispersion) <<
" ";
1221 std::cout.precision(2);
1222 std::cout << sigmaCut <<
" ";
1223 std::cout << (*configuration).
print() <<
" ";
1224 std::cout.precision(6);
1225 std::cout << timer.getAverageTime() <<
" " << timer.getStandardDeviation() <<
" " << timer.getCoefficientOfVariation();
1226 std::cout << std::endl;
1230 if ( parameters.getBestMode() )
1232 std::cout.precision(2);
1233 std::cout << observation.getNrSamplesPerDispersedBatch(subbandDedispersion) <<
" " << sigmaCut <<
" ";
1234 std::cout << bestConfig.
print() << std::endl;
1238 std::cout << std::endl;
std::string * getFrequencyDomainSigmaCutOpenCL_FrequencyTime_ReplaceWithMean(const RFImConfig &config, const std::string &dataTypeName, const AstroData::Observation &observation, const unsigned int nrBins, const float sigmaCut, const unsigned int padding)
Generates the OpenCL code for the frequency domain sigma cut. This function generates specialized cod...
Definition: RFIm.hpp:822
void testTimeDomainSigmaCut(const bool printCode, const bool printResults, const RFImConfig &config, const DataOrdering &ordering, const ReplacementStrategy &replacement, const std::string &dataTypeName, const AstroData::Observation &observation, const std::vector< DataType > &time_series, isa::OpenCL::OpenCLRunTime &openCLRunTime, const unsigned int clDeviceID, const float sigmaCut, const unsigned int padding)
Test the OpenCL kernel by comparing results with C++ implementation.
Definition: RFIm.hpp:517
void tuneTimeDomainSigmaCut(const bool subbandDedispersion, const isa::OpenCL::TuningParameters ¶meters, const DataOrdering &ordering, const ReplacementStrategy &replacement, const std::string &dataTypeName, const AstroData::Observation &observation, const std::vector< DataType > &time_series, const unsigned int clPlatformID, const unsigned int clDeviceID, const float sigmaCut, const unsigned int padding)
Tune the OpenCL kernel to find best performing configuration for a certain scenario.
Definition: RFIm.hpp:619
RFImKernel
The kernel type.
Definition: RFIm.hpp:76
std::string * getFrequencyDomainSigmaCutOpenCL(const RFImConfig &config, const DataOrdering &ordering, const ReplacementStrategy &replacement, const std::string &dataTypeName, const AstroData::Observation &observation, const unsigned int nrBins, const float sigmaCut, const unsigned int padding)
Generates the OpenCL code for the frequency domain sigma cut.
Definition: RFIm.hpp:812
DataOrdering
Ordering of input/output data.
Definition: RFIm.hpp:85
std::map< std::string, std::map< unsigned int, std::map< float, RFImConfig * > * > * > RFImConfigurations
Definition: RFIm.hpp:100
bool getSubbandDedispersion() const
Return true if in subbanding mode, false otherwise.
Definition: RFIm.hpp:292
std::string * getTimeDomainSigmaCutOpenCL_FrequencyTime_ReplaceWithMean(const RFImConfig &config, const std::string &dataTypeName, const AstroData::Observation &observation, const float sigmaCut, const unsigned int padding)
Generates the OpenCL code for the time domain sigma cut. This function generates specialized code for...
Definition: RFIm.hpp:361
void readSigmaSteps(const std::string &inputFilename, std::vector< float > &steps)
Read the.
Definition: RFIm.cpp:108
void setSubbandDedispersion(const bool subband)
Set the subbanding mode.
Definition: RFIm.hpp:302
void tuneFrequencyDomainSigmaCut(const bool subbandDedispersion, const isa::OpenCL::TuningParameters ¶meters, const DataOrdering &ordering, const ReplacementStrategy &replacement, const std::string &dataTypeName, const AstroData::Observation &observation, const std::vector< DataType > &time_series, const unsigned int clPlatformID, const unsigned int clDeviceID, const unsigned int nrBins, const float sigmaCut, const unsigned int padding)
Tune the OpenCL kernel to find best performing configuration for a certain scenario.
Definition: RFIm.hpp:1092
RFImConfig()
Definition: RFIm.cpp:20
std::string print() const
Print the configuration.
Definition: RFIm.hpp:312
void testFrequencyDomainSigmaCut(const bool printCode, const bool printResults, const RFImConfig &config, const DataOrdering &ordering, const ReplacementStrategy &replacement, const std::string &dataTypeName, const AstroData::Observation &observation, const std::vector< DataType > &time_series, isa::OpenCL::OpenCLRunTime &openCLRunTime, const unsigned int clDeviceID, const unsigned int nrBins, const float sigmaCut, const unsigned int padding)
Test the OpenCL kernel by comparing results with C++ implementation.
Definition: RFIm.hpp:990
bool getConditionalReplacement() const
Return true if using a condition for replacement, false otherwise.
Definition: RFIm.hpp:297
void setConditionalReplacement(const bool replacement)
Set the conditional replacement mode.
Definition: RFIm.hpp:307
void readRFImConfig(RFImConfigurations &configurations, const std::string &filename)
Read one RFImConfig from a configuration file.
Definition: RFIm.cpp:24
ReplacementStrategy
Strategy for flagged data replacement.
Definition: RFIm.hpp:94
~RFImConfig()
Definition: RFIm.cpp:22
RFI specific kernel configuration.
Definition: RFIm.hpp:42
std::string * getTimeDomainSigmaCutOpenCL(const RFImConfig &config, const DataOrdering &ordering, const ReplacementStrategy &replacement, const std::string &dataTypeName, const AstroData::Observation &observation, const float sigmaCut, const unsigned int padding)
Generates the OpenCL code for the time domain sigma cut.
Definition: RFIm.hpp:351
std::uint64_t timeDomainSigmaCut(const bool subbandDedispersion, const DataOrdering &ordering, const ReplacementStrategy &replacement, const AstroData::Observation &observation, std::vector< DataType > &time_series, const float sigmaCut, const unsigned int padding)
Compute time domain sigma cut. Not optimized, just for testing purpose.
Definition: RFIm.hpp:318
std::uint64_t frequencyDomainSigmaCut(const bool subbandDedispersion, const DataOrdering &ordering, const ReplacementStrategy &replacement, const AstroData::Observation &observation, std::vector< DataType > &time_series, const unsigned int nrBins, const float sigmaCut, const unsigned int padding)
Compute frequency domain sigma cut. Not optimized, just for testing purpose.
Definition: RFIm.hpp:766