void TuneFilterDecimate_i::TuningRFChanged(const CORBA::ULongLong *oldValue, const CORBA::ULongLong *newValue) { if (*oldValue != *newValue) { boost::mutex::scoped_lock lock(TuneFilterDecimateLock_); configureTuner("TuningRF"); } }
void TuneFilterDecimate_i::TuningIFChanged(const double *oldValue, const double *newValue) { if (*oldValue != *newValue) { boost::mutex::scoped_lock lock(TuneFilterDecimateLock_); configureTuner("TuningIF"); } }
void TuneFilterDecimate_i::configureTFD(BULKIO::StreamSRI &sri) { LOG_TRACE(TuneFilterDecimate_i, "Configuring SRI: " << "sri.xdelta = " << sri.xdelta << "sri.streamID = " << sri.streamID) Real tmpInputSampleRate = 1 / sri.xdelta; // Calculate sample rate received from SRI bool lastInputComplex = inputComplex; if (sri.mode==1) { inputComplex=true; chan_if =0.0; //center of band is 0 if we are complex } else { inputComplex = false; chan_if = tmpInputSampleRate/4.0; //center of band is fs/4 if we are real //output is always complex even if input is real sri.mode=1; } DecimationFactor = floor(tmpInputSampleRate/DesiredOutputRate); LOG_DEBUG(TuneFilterDecimate_i, "DecimationFactor = " << DecimationFactor); if (DecimationFactor <1) { LOG_WARN(TuneFilterDecimate_i, "Decimation less than 1, setting to minimum") DecimationFactor=1; } bool sampleRateChanged =(InputRate != tmpInputSampleRate); if (sampleRateChanged) { InputRate = tmpInputSampleRate; LOG_DEBUG(TuneFilterDecimate_i, "Sample rate changed: InputRate = " << InputRate); } // Calculate new output sample rate & modify the referenced SRI structure ActualOutputRate = InputRate / DecimationFactor; sri.xdelta = 1.0 / ActualOutputRate; LOG_DEBUG(TuneFilterDecimate_i, "Output xdelta = " << sri.xdelta << " ActualOutputRate " << ActualOutputRate); if (ActualOutputRate < FilterBW) LOG_WARN(TuneFilterDecimate_i, "ActualOutputRate " << ActualOutputRate << " is less than FilterBW " << FilterBW); // Retrieve the front-end collected RF to determine the IF bool validCollectionRF = false; bool validChannelRF = false; double collection_rf = getKeywordByID<CORBA::Double>(sri, "COL_RF", validCollectionRF); double channel_rf = getKeywordByID<CORBA::Double>(sri, "CHAN_RF", validChannelRF); double tmpInputRF; if ((validCollectionRF) && (validChannelRF)) { LOG_WARN(TuneFilterDecimate_i, "Input SRI contains both COL_RF and CHAN_RF, using CHAN_RF"); tmpInputRF = channel_rf; } else if (validCollectionRF) { tmpInputRF = collection_rf; } else if (validChannelRF) { tmpInputRF = channel_rf; } else { if (TuneMode == "RF") { LOG_WARN(TuneFilterDecimate_i, "Input SRI lacks RF keyword. RF tuning cannot be performed."); return; } tmpInputRF = 0; } bool inputComplexChanged = lastInputComplex ^ inputComplex; if (tmpInputRF != InputRF) { LOG_DEBUG(TuneFilterDecimate_i, "Input RF changed " << tmpInputRF); InputRF = tmpInputRF; // If the TuneMode is RF, we actually need to retune if (TuneMode == "RF") { configureTuner("TuningRF"); } else if (TuneMode == "NORM") { configureTuner("TuningNorm"); } TuningRF = InputRF + TuningIF - chan_if; LOG_DEBUG(TuneFilterDecimate_i, "Tuning RF: " << TuningRF); } else if (TuneMode == "RF" && inputComplexChanged) { //the RF didn't change but the IF is changing because we have switched between real and complex data configureTuner("TuningRF"); LOG_DEBUG(TuneFilterDecimate_i, "Tuning RF: " << TuningRF); } // Add the CHAN_RF keyword to the SRI if we know the input RF if (InputRF != 0) { if(!setKeywordByID<CORBA::Double>(sri, "CHAN_RF", (double)TuningRF)) LOG_WARN(TuneFilterDecimate_i, "SRI Keyword CHAN_RF could not be set."); } // Reconfigure the tuner classes only if the sample rate has changed if ((tuner== NULL) || sampleRateChanged) { LOG_DEBUG(TuneFilterDecimate_i, "Remaking tuner"); if (tuner != NULL) { delete tuner; } if (TuneMode == "NORM") { configureTuner("TuningNorm"); } else if (TuneMode == "IF") { configureTuner("TuningIF"); } else if (TuneMode == "RF") { configureTuner("TuningRF"); } tuner = new Tuner(tunerInput, f_complexIn, TuningNorm); } if ((filter==NULL) || sampleRateChanged || RemakeFilter) { LOG_DEBUG(TuneFilterDecimate_i, "Remaking filter"); if((filter != NULL) || (decimate != NULL)) { delete filter; delete decimate; } /* * ASCII ART to explain the filter design * * Lowpass (Real filter) * ---------| * \ * \ * \ * | * ---------------------------------- * 0 FL FL+tw fsOut/2 fsIn/2 * * The basic gist is we tune first, then filter. * Then we filter * Then we decimate * * This means the filter is a LOWPASS filter which must be designed given the INPUT sampling frequency. * The transition frequency happens at 1/2 the requested tune bandwidth. Thus FL = FilterBW / 2.0. * We need the transition region to "finish" by fsOut/2 to avoid aliasing, so we do a check for that too. * */ Real FL = FilterBW / 2.0; //calculate the transition frequency necessary to avoid aliasing Real maxTW = (ActualOutputRate/2.0)-FL; if (maxTW > 0 && maxTW < filterProps.TransitionWidth) { LOG_WARN(TuneFilterDecimate_i, "input transition width "<< filterProps.TransitionWidth<<" too large - replacing with "<< maxTW); filterProps.TransitionWidth = maxTW; } // We generate our FIR filter taps here. The read-only property 'taps' is set. // - We use the transition width and ripple specified by the user to create the filter taps. // - Normalized lowpass cutoff frequency is the only one we need; upper cutoff not used RealVector tmpVec; taps = filterdesigner_.wdfirHz(tmpVec, FIRFilter::lowpass, filterProps.Ripple, filterProps.TransitionWidth, FL, 0, InputRate, MIN_NUM_TAPS, MAX_NUM_TAPS); filterCoeff.clear(); filterCoeff.reserve(tmpVec.size()); for (RealVector::iterator i = tmpVec.begin(); i!=tmpVec.end(); i++) filterCoeff.push_back(*i); // Minimum FFT_size implemented size_t minFftSize = std::max(MIN_FFT_SIZE, pow2ge(2*taps)); if(filterProps.FFT_size < minFftSize) { LOG_DEBUG(TuneFilterDecimate_i, "FFT_size too small, set to " << minFftSize); filterProps.FFT_size = minFftSize; } else if (filterProps.FFT_size > MAX_FFT_SIZE) { LOG_DEBUG(TuneFilterDecimate_i, "FFT_size too large, set to " << MAX_FFT_SIZE); filterProps.FFT_size = MAX_FFT_SIZE; } filter = new firfilter(filterProps.FFT_size, f_realOut, f_complexOut, filterCoeff); decimate = new Decimate(f_complexOut, decimateOutput, DecimationFactor); RemakeFilter = false; } LOG_TRACE(TuneFilterDecimate_i, "Exit configureSRI()"); }
void init(CodecConfiguration *configuration) { // Need to initialize loggers. // Then need to pre-allocate pinned memory and Cuda Global Memory. gpuTunerCategory = log4c_category_get("performance_tuning_gpu_logger"); cpuTunerCategory = log4c_category_get("performance_tuning_cpu_logger"); log4c_init(); currentMode = PRODUCTION; config_t propConfig; config_init(&propConfig); if (!config_read_file(&propConfig, configuration->propertyFilePath)) { fprintf(stderr, "%s:%d - %s\n", config_error_file(&propConfig), config_error_line(&propConfig), config_error_text(&propConfig)); config_destroy(&propConfig); return; } config_lookup_bool(&propConfig, "isUseGpu", &useGpu); config_lookup_bool(&propConfig, "isUseDynamicParallelism", &useDynamicParallelism); config_lookup_int(&propConfig, "max_packet_size", &maxPacketSize); config_lookup_int(&propConfig, "max_batch_size", &maxBatchSize); config_lookup_int(&propConfig, "tuner_loop_count", &tunerLoopCount); config_lookup_int(&propConfig, "number_of_cpu_cores", &nCpuCores); config_lookup_int(&propConfig, "cuda_stream_count", &cudaStreamCount); config_lookup_bool(&propConfig, "print_accuracy_log", &printAccuracyLog); currentCudaContextSize = (uint32_t) maxBatchSize; cudaPduContext = allocatePinnedPduContext(maxBatchSize); initCudaParameters((uint32_t) maxBatchSize, ((uint64_t) maxPacketSize * (uint64_t) maxBatchSize)); int isTunerMode = 0; config_lookup_bool(&propConfig, "isTunerMode", &isTunerMode); currentMode = isTunerMode ? TUNER : PRODUCTION; printf("Is Use GPU %d | Max Packet Size %d | Max Batch Size %d | Tuner Mode %d | Accuracy Log %d\n", useGpu, maxPacketSize, maxBatchSize, currentMode, printAccuracyLog); fflush(stdout); switch (currentMode) { case TUNER: { configureTuner(&propConfig); break; } default: { int x, y, z; config_setting_t *block = config_lookup(&propConfig, "production.block"); config_setting_t *grid = config_lookup(&propConfig, "production.grid"); config_setting_lookup_int(block, "x", &x); config_setting_lookup_int(block, "y", &y); config_setting_lookup_int(block, "z", &z); blockDimProdction.x = (uint32_t) x; blockDimProdction.y = (uint32_t) y; blockDimProdction.z = (uint32_t) z; config_setting_lookup_int(grid, "x", &x); config_setting_lookup_int(grid, "y", &y); config_setting_lookup_int(grid, "z", &z); gridDimProduction.x = (uint32_t) x; gridDimProduction.y = (uint32_t) y; gridDimProduction.z = (uint32_t) z; config_lookup_int(&propConfig, "production.cpu_decode_threshold", &cpuDecodeThreshold); } } }