Cheetah - SKA - PSS - Prototype Time Domain Search Pipeline
SpsCuda.cpp
1 /*
2  * The MIT License (MIT)
3  *
4  * Copyright (c) 2016 The SKA organisation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "cheetah/sps/astroaccelerate/detail/SpsCuda.h"
25 #include "cheetah/cuda_utils/cuda_errorhandling.h"
26 #include "cheetah/data/TimeFrequency.h"
27 #include "cheetah/data/Units.h"
28 #include "panda/Resource.h"
29 #include "panda/Log.h"
30 #include <memory>
31 #include <algorithm>
32 #include <limits>
33 
34 namespace ska {
35 namespace cheetah {
36 namespace sps {
37 namespace astroaccelerate {
38 
39 #ifdef ENABLE_ASTROACCELERATE
40 
41 SpsCuda::SpsCuda(sps::Config const& config)
42  : BaseT(config.astroaccelerate_config(), config)
43 {
44  // Get the dedispersion plan
45  auto it = config.subsection("dedispersion");
46  while (it != config.subsection_end())
47  {
48  ddtr::DedispersionConfig const& c = static_cast<ddtr::DedispersionConfig const&>(*it);
49  _dedisp_configs.push_back(&c);
50  ++it;
51  }
52  // Get the detection threshold
53  _threshold = config.threshold();
54  _samples = config.dedispersion_samples();
55 }
56 
57 SpsCuda::~SpsCuda()
58 {
59 }
60 
61 std::size_t SpsCuda::buffer_overlap() const
62 {
63  assert(_samples > _dedispersion_strategy->get_dedispersed_time_samples());
64  return _samples - _dedispersion_strategy->get_dedispersed_time_samples();
65 }
66 
67 ::astroaccelerate::DedispersionStrategy const& SpsCuda::dedispersion_strategy() const
68 {
69  return *_dedispersion_strategy;
70 }
71 
72 // This should be pased a TimeFrequency object
73 std::size_t SpsCuda::set_dedispersion_strategy(std::size_t min_gpu_memory, TimeFrequencyType const& tf_data)
74 {
75  PANDA_LOG_DEBUG << "Setting SpsCuda dedispersion strategy. GPU memory=" << min_gpu_memory;
76  std::size_t nranges = _dedisp_configs.size();
77  if (nranges == 0)
78  {
79  throw panda::Error("No dedispersion plan set.");
80  }
81  std::vector<float> user_dm_low;
82  std::vector<float> user_dm_high;
83  std::vector<float> user_dm_step;
84  std::vector<int> in_bin;
85  std::vector<int> out_bin;
86 
87  for (auto& config: _dedisp_configs)
88  {
89  PANDA_LOG << "Configuring DM range: "
90  << (float)config->dm_start().value() << " to "
91  << (float)config->dm_end().value() << " pc/cc in steps of "
92  << (float)config->dm_step().value() << " pc/cc";
93  user_dm_low.push_back((float)config->dm_start().value());
94  user_dm_high.push_back((float)config->dm_end().value());
95  user_dm_step.push_back((float)config->dm_step().value());
96  PANDA_LOG << "Disabling downsampling for DM range";
97  in_bin.push_back(1);
98  out_bin.push_back(1);
99  }
100 
101  _chan_high = FrequencyType(0.0*boost::units::si::hertz);
102  _chan_low = FrequencyType(std::numeric_limits<typename FrequencyType::value_type>::max()*boost::units::si::hertz);
103  std::vector<float> chan_freqs;
104  for (auto const& freq: tf_data.channel_frequencies())
105  {
106  if (freq > _chan_high)
107  {
108  _chan_high = freq;
109  }
110  else if( freq < _chan_low )
111  {
112  _chan_low = freq;
113  }
114  chan_freqs.push_back(freq.value());
115  }
116 
117  PANDA_LOG_DEBUG << "Generating new DedispersionStrategy object";
118  PANDA_LOG_DEBUG << "User-requested samples to dedisperse: " << _samples;
119  _dedispersion_strategy.reset( new ::astroaccelerate::DedispersionStrategy(
120  user_dm_low
121  , user_dm_high
122  , user_dm_step
123  , in_bin
124  , out_bin
125  , std::max(ArchitectureCapability::total_memory, min_gpu_memory) //gpu_memory
126  , 8 //power
127  ,(int) _dedisp_configs.size()
128  ,_samples //nsamples
129  ,1 //nifs -- not used by DedispersionStrategy
130  ,8 //nbits -- not used by DedispersionStrategy
131  ,tf_data.sample_interval().value() //tsamp (assumed to be in seconds)
132  ,_threshold //sigma_cutoff
133  ,6 //sigma_constant
134  ,0.5 //max_boxcar_width_in_sec
135  ,0 //narrow -- not used
136  ,0 //wide -- not used
137  ,0 //nboots -- not used
138  ,0 //navdms -- not used
139  ,0 //ntrial_bins -- not used
140  ,0 //nsearch -- not used
141  ,0 //aggression -- not used
142  ,chan_freqs //chan frequency array
143  ));
144 
145  return calculate_internals(tf_data.sample_interval());
146 }
147 
148 std::size_t SpsCuda::calculate_internals(TimeType samp_interval)
149 {
150  PANDA_LOG_DEBUG << "Calculating SpsCuda output sizes";
151 
152  _dm_time.reset(new ::astroaccelerate::DmTime<float>(*_dedispersion_strategy));
153 
154  std::size_t nranges = _dm_time->number_of_dm_ranges();
155 
156  std::size_t nsamps_processed = *std::max_element(_dm_time->nsamples().begin(), _dm_time->nsamples().end());
157 
158  _dm_trial_metadata.reset(new data::DmTrialsMetadata(samp_interval, nsamps_processed));
159 
160  for (std::size_t range=0; range < nranges; ++range)
161  {
162  std::size_t ndms = std::size_t(_dedispersion_strategy->get_ndms()[range]);
163  data::DedispersionMeasureType<float> dm(_dedispersion_strategy->get_dm_low()[range] * data::parsecs_per_cube_cm);
164  data::DedispersionMeasureType<float> dm_step(_dedispersion_strategy->get_dm_step()[range] * data::parsecs_per_cube_cm);
165  std::size_t size = _dm_time->nsamples()[range];
166 
167  for (std::size_t dm_idx =0; dm_idx < ndms; ++dm_idx)
168  {
169  _dm_trial_metadata->emplace_back(dm,nsamps_processed/size);
170  dm = dm + dm_step;
171  }
172  }
173 
174  return _samples;
175 }
176 #endif // ENABLE_ASTROACCELERATE
177 
178 } // namespace astroaccelerate
179 } // namespace sps
180 } // namespace cheetah
181 } // namespace ska
Some limits and constants for FLDO.
Definition: Brdz.h:35