1 #ifndef MHO_EndZeroPadderOptimized_HH__
2 #define MHO_EndZeroPadderOptimized_HH__
35 for(std::size_t i = 0; i < XArgType::rank::value; i++)
37 fInputDimensionSize[i] = 0;
38 fOutputDimensionSize[i] = 0;
39 fAxesToXForm[i] =
true;
46 fPreserveWorkspace =
false;
48 fTmpWorkspace =
nullptr;
49 fHasPaddedAxis =
false;
50 fInnermostPaddedAxis = 0;
54 for(std::size_t i = 0; i < XArgType::rank::value; i++)
81 fPaddedSize = new_size;
115 fPreserveWorkspace =
true;
143 for(std::size_t i = 0; i < XArgType::rank::value; i++)
145 fAxesToXForm[i] =
true;
154 for(std::size_t i = 0; i < XArgType::rank::value; i++)
156 fAxesToXForm[i] =
false;
167 if(axis_index < XArgType::rank::value)
169 fAxesToXForm[axis_index] =
true;
173 msg_error(
"operators",
"Cannot transform axis with index: " << axis_index <<
"for array with rank: "
174 << XArgType::rank::value << eom);
188 if(fTmpWorkspace ==
nullptr)
190 fTmpWorkspace =
new XArgType();
205 in->Copy(*fTmpWorkspace);
206 if(!fPreserveWorkspace)
209 delete fTmpWorkspace;
210 fTmpWorkspace =
nullptr;
225 if(in !=
nullptr && out !=
nullptr && in != out)
233 in->GetDimensions(fInputDimensionSize);
234 out->GetDimensions(fOutputDimensionSize);
235 ConditionallyResizeOutput(in->GetDimensionArray(), out);
236 PrecomputeOffsetTables();
239 return (fInitialized && fIsValid);
251 if(fIsValid && fInitialized)
254 constexpr std::size_t RANK = XArgType::rank::value;
255 const auto* in_data = in->GetData();
256 auto* out_data = out->GetData();
267 const std::size_t block_bytes = fBlockElems *
sizeof(*in_data);
268 std::size_t idx[RANK] = {};
269 std::size_t in_offset = 0, out_offset = 0;
270 for(std::size_t row = 0; row < fNRows; row++)
272 std::memcpy(out_data + out_offset, in_data + in_offset, block_bytes);
274 for(
int d = (
int)fInnermostPaddedAxis - 1; d >= 0; d--)
277 in_offset += fInStride[d];
278 out_offset += fOutStride[d];
279 if(idx[d] < fInputDimensionSize[d])
282 in_offset -= fInputDimensionSize[d] * fInStride[d];
283 out_offset -= fInputDimensionSize[d] * fOutStride[d];
290 std::memcpy(out_data, in_data, fTotalInputElems *
sizeof(*in_data));
298 std::size_t axis_out_offset[RANK];
299 std::size_t out_flat = 0;
300 for(std::size_t d = 0; d < RANK; d++)
302 axis_out_offset[d] = fOutAxisOffset[d][0];
303 out_flat += axis_out_offset[d];
305 std::size_t idx[RANK] = {};
306 for(std::size_t n = 0; n < fTotalInputElems; n++)
308 out_data[out_flat] = in_data[n];
310 for(
int d = (
int)RANK - 1; d >= 0; d--)
313 if(idx[d] < fInputDimensionSize[d])
315 std::size_t new_contrib = fOutAxisOffset[d][idx[d]];
316 out_flat = out_flat - axis_out_offset[d] + new_contrib;
317 axis_out_offset[d] = new_contrib;
323 std::size_t new_contrib = fOutAxisOffset[d][0];
324 out_flat = out_flat - axis_out_offset[d] + new_contrib;
325 axis_out_offset[d] = new_contrib;
332 IfTableTransformAxis(in, out);
337 msg_error(
"operators",
"Array dimensions are not valid or intialization failed. Aborting zero padding." << eom);
351 template<
typename XCheckType = XArgType >
352 typename std::enable_if< !std::is_base_of< MHO_TableContainerBase, XCheckType >::value,
void >::type
353 IfTableTransformAxis(
const XArgType* , XArgType* ){};
356 template<
typename XCheckType = XArgType >
357 typename std::enable_if< std::is_base_of< MHO_TableContainerBase, XCheckType >::value,
void >::type
358 IfTableTransformAxis(
const XArgType* in, XArgType* out)
360 for(
size_t i = 0; i < XArgType::rank::value; i++)
362 TransformAxis axis_transformer(fAxesToXForm[i], fFlipped, fCopyTags);
363 apply_at2< typename XArgType::axis_pack_tuple_type, TransformAxis >(*in, *out, i, axis_transformer);
371 TransformAxis(
bool modify,
bool flipped,
bool copy_tags)
372 : fModify(modify), fFlipped(flipped), fCopyTags(copy_tags){};
377 template<
typename XAxisType >
void operator()(
const XAxisType& axis1, XAxisType& axis2)
381 CopyLabelsWithoutTags(axis1, axis2);
395 std::size_t ax1_size = axis1.
GetSize();
396 std::size_t ax2_size = axis2.
GetSize();
399 CopyLabelsWithoutTags(axis1, axis2);
411 double delta = axis1(1) - axis1(0);
414 for(std::size_t i = 0; i < ax1_size; i++)
418 for(std::size_t i = ax1_size; i < ax2_size; i++)
420 axis2(i) = axis1(ax1_size - 1) + (i - (ax1_size - 1)) * delta;
425 for(std::size_t i = 0; i < ax1_size; i++)
427 axis2(i) = axis1(ax1_size - 1 - i);
429 for(std::size_t i = ax1_size; i < ax2_size; i++)
431 axis2(i) = axis1(0) - (i - (ax1_size - 1)) * delta;
436 void operator()(
const MHO_Axis< float >& axis1, MHO_Axis< float >& axis2)
438 std::size_t ax1_size = axis1.
GetSize();
439 std::size_t ax2_size = axis2.GetSize();
442 CopyLabelsWithoutTags(axis1, axis2);
452 axis2.Resize(ax2_size);
454 double delta = axis1(1) - axis1(0);
457 for(std::size_t i = 0; i < ax1_size; i++)
461 for(std::size_t i = ax1_size; i < ax2_size; i++)
463 axis2(i) = axis1(ax1_size - 1) + (i - (ax1_size - 1)) * delta;
468 for(std::size_t i = 0; i < ax1_size; i++)
470 axis2(i) = axis1(ax1_size - 1 - i);
472 for(std::size_t i = ax1_size; i < ax2_size; i++)
474 axis2(i) = axis1(0) - (i - (ax1_size - 1)) * delta;
480 template<
typename XAxisType >
void CopyLabelsWithoutTags(
const XAxisType& axis1, XAxisType& axis2)
483 std::size_t ax1_size = axis1.GetSize();
484 std::size_t ax2_size = axis2.GetSize();
485 std::size_t s =
std::min(ax1_size, ax2_size);
486 for(std::size_t i = 0; i < s; i++)
497 void PrecomputeOffsetTables()
499 constexpr std::size_t RANK = XArgType::rank::value;
502 fInStride[RANK - 1] = 1;
503 fOutStride[RANK - 1] = 1;
504 for(
int d = (
int)RANK - 2; d >= 0; d--)
506 fInStride[d] = fInStride[d + 1] * fInputDimensionSize[d + 1];
507 fOutStride[d] = fOutStride[d + 1] * fOutputDimensionSize[d + 1];
511 fHasPaddedAxis =
false;
512 fInnermostPaddedAxis = 0;
513 for(std::size_t d = 0; d < RANK; d++)
517 fInnermostPaddedAxis = d;
518 fHasPaddedAxis =
true;
527 for(std::size_t d = fInnermostPaddedAxis; d < RANK; d++)
528 fBlockElems *= fInputDimensionSize[d];
529 for(std::size_t d = 0; d < fInnermostPaddedAxis; d++)
530 fNRows *= fInputDimensionSize[d];
534 fTotalInputElems = 1;
535 for(std::size_t d = 0; d < RANK; d++)
536 fTotalInputElems *= fInputDimensionSize[d];
540 fOutAxisOffset.resize(RANK);
541 for(std::size_t d = 0; d < RANK; d++)
543 fOutAxisOffset[d].resize(fInputDimensionSize[d]);
544 for(std::size_t k = 0; k < fInputDimensionSize[d]; k++)
548 fOutAxisOffset[d][k] = k * fOutStride[d];
550 else if(!fNormFXMode)
552 fOutAxisOffset[d][k] = (fOutputDimensionSize[d] - 1 - k) * fOutStride[d];
558 fOutAxisOffset[d][k] = (fOutputDimensionSize[d] / 2) * fOutStride[d];
560 fOutAxisOffset[d][k] = (fOutputDimensionSize[d] - k) * fOutStride[d];
566 void ConditionallyResizeOutput(
const std::array< std::size_t, XArgType::rank::value >& dims, XArgType* out)
568 auto out_dim = out->GetDimensionArray();
569 bool have_to_resize =
false;
570 for(std::size_t i = 0; i < XArgType::rank::value; i++)
574 if(dims[i] * fPaddingFactor != out_dim[i])
576 have_to_resize =
true;
577 out_dim[i] = dims[i] * fPaddingFactor;
579 if(fPaddingFactor == 1)
581 if(dims[i] != fPaddedSize)
583 have_to_resize =
true;
584 out_dim[i] = fPaddedSize;
590 if(dims[i] != out_dim[i])
592 have_to_resize =
true;
593 out_dim[i] = dims[i];
599 out->Resize(&(out_dim[0]));
601 out->GetDimensions(fOutputDimensionSize);
608 bool fPreserveWorkspace;
611 std::size_t fPaddingFactor;
612 std::size_t fPaddedSize;
613 std::size_t fInputDimensionSize[XArgType::rank::value];
614 std::size_t fOutputDimensionSize[XArgType::rank::value];
615 bool fAxesToXForm[XArgType::rank::value];
619 std::size_t fInnermostPaddedAxis;
620 std::size_t fBlockElems;
622 std::size_t fTotalInputElems;
623 std::size_t fInStride[XArgType::rank::value];
624 std::size_t fOutStride[XArgType::rank::value];
625 std::vector< std::vector< std::size_t > > fOutAxisOffset;
627 XArgType* fTmpWorkspace;
#define msg_error(xKEY, xCONTENT)
Definition: MHO_Message.hh:238
#define profiler_scope()
Definition: MHO_Profiler.hh:237
virtual void Copy(const MHO_Axis &rhs)
Expensive copy for MHO_Axis that handles special treatment of index/interval labels.
Definition: MHO_Axis.hh:200
Class MHO_EndZeroPadderOptimized.
Definition: MHO_EndZeroPadderOptimized.hh:29
virtual bool ExecuteInPlace(XArgType *in) override
Executes operation in-place by copying temporary workspace back to input object.
Definition: MHO_EndZeroPadderOptimized.hh:201
void DeselectAllAxes()
Deselects all axes by setting each axis to false.
Definition: MHO_EndZeroPadderOptimized.hh:152
virtual void SetReverseEndPadded()
Setter for reverse end padded, place data at end of array and zero pad out to start.
Definition: MHO_EndZeroPadderOptimized.hh:95
virtual void SetPaddedSize(std::size_t new_size)
Setter for padded size, instead of a multiplicative factor, the original array, length N is padded ou...
Definition: MHO_EndZeroPadderOptimized.hh:79
virtual void DisableTagCopy()
Disables copying tags by setting fCopyTags to false.
Definition: MHO_EndZeroPadderOptimized.hh:128
virtual bool InitializeOutOfPlace(const XArgType *in, XArgType *out) override
Initializes out-of-place processing for input and output arrays.
Definition: MHO_EndZeroPadderOptimized.hh:223
virtual void DisableNormFXMode()
Disables Normal Mapping FX Mode by setting fNormFXMode to false. UNUSED - TODO REMOVE ME!
Definition: MHO_EndZeroPadderOptimized.hh:101
virtual ~MHO_EndZeroPadderOptimized()
Definition: MHO_EndZeroPadderOptimized.hh:61
MHO_EndZeroPadderOptimized()
Definition: MHO_EndZeroPadderOptimized.hh:31
void SelectAllAxes()
Selects all axes for transformation. sometimes we may want to select/deselect particular dimensions o...
Definition: MHO_EndZeroPadderOptimized.hh:141
virtual void SetEndPadded()
Setter for end padded, zero padding from end of data out to end of the array.
Definition: MHO_EndZeroPadderOptimized.hh:89
virtual void EnableNormFXMode()
Enables Normalized FX Mode by setting fNormFXMode to true. UNUSED - TODO REMOVE ME!
Definition: MHO_EndZeroPadderOptimized.hh:107
virtual void EnableTagCopy()
Enables copying of tags.
Definition: MHO_EndZeroPadderOptimized.hh:134
virtual void SetPaddingFactor(std::size_t factor)
Setter for padding factor, the factor M by which the new array will be extended (original array,...
Definition: MHO_EndZeroPadderOptimized.hh:70
virtual void PreserveWorkspace()
Sets a flag to preserve workspace memory after execution.
Definition: MHO_EndZeroPadderOptimized.hh:113
void SelectAxis(std::size_t axis_index)
Selects an axis for transformation if its index is within the array rank.
Definition: MHO_EndZeroPadderOptimized.hh:165
virtual bool ExecuteOutOfPlace(const XArgType *in, XArgType *out) override
Function ExecuteOutOfPlace.
Definition: MHO_EndZeroPadderOptimized.hh:249
virtual void DoNotPreserveWorkspace()
Sets preserve workspace flag to false, delete memory after execution.
Definition: MHO_EndZeroPadderOptimized.hh:122
virtual bool InitializeInPlace(XArgType *in) override
Initializes in-place by creating a temporary workspace and calling InitializeOutOfPlace.
Definition: MHO_EndZeroPadderOptimized.hh:186
virtual void Resize(const std::size_t *dim)
Resize an externally managed array using provided dimensions.
Definition: MHO_NDArrayWrapper_1.hh:52
std::size_t GetSize() const
Getter for size.
Definition: MHO_NDArrayWrapper_1.hh:99
Class MHO_UnaryOperator.
Definition: MHO_UnaryOperator.hh:24
struct type_status status
Definition: fourfit3.c:53
#define min(a, b)
Definition: max555.c:9
Definition: MHO_AdhocFlagging.hh:18