From c4e55ca0e7db087f3d7c63dd605b5f206a63e9b2 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Mon, 22 Sep 2025 02:30:31 -0500 Subject: [PATCH 001/118] Use enums present in commons.h Remove the usage of API enums in internal node files --- .../node_mel_filter_bank.h | 3 +- .../node_preemphasis_filter.h | 5 +- .../geometry_augmentations/node_crop_resize.h | 4 +- .../geometry_augmentations/node_resize.h | 7 ++- .../node_resize_crop_mirror.h | 4 +- .../node_resize_mirror_normalize.h | 6 +-- .../geometry_augmentations/node_rotate.h | 5 +- .../geometry_augmentations/node_slice.h | 5 +- .../geometry_augmentations/node_warp_affine.h | 4 +- rocAL/include/pipeline/commons.h | 51 ++++++++++++++++++- rocAL/source/api/rocal_api_augmentation.cpp | 22 ++++---- rocAL/source/api/rocal_api_data_loaders.cpp | 4 +- .../node_mel_filter_bank.cpp | 2 +- .../node_preemphasis_filter.cpp | 2 +- .../node_crop_resize.cpp | 4 +- .../geometry_augmentations/node_resize.cpp | 14 ++--- .../node_resize_crop_mirror.cpp | 4 +- .../node_resize_mirror_normalize.cpp | 14 ++--- .../geometry_augmentations/node_rotate.cpp | 4 +- .../geometry_augmentations/node_slice.cpp | 2 +- .../node_warp_affine.cpp | 4 +- 21 files changed, 107 insertions(+), 63 deletions(-) diff --git a/rocAL/include/augmentations/audio_augmentations/node_mel_filter_bank.h b/rocAL/include/augmentations/audio_augmentations/node_mel_filter_bank.h index 254eccc4e..4902f0c8c 100644 --- a/rocAL/include/augmentations/audio_augmentations/node_mel_filter_bank.h +++ b/rocAL/include/augmentations/audio_augmentations/node_mel_filter_bank.h @@ -23,13 +23,12 @@ THE SOFTWARE. #pragma once #include "pipeline/graph.h" #include "pipeline/node.h" -#include "rocal_api_types.h" class MelFilterBankNode : public Node { public: MelFilterBankNode(const std::vector &inputs, const std::vector &outputs); MelFilterBankNode() = delete; - void init(float freq_high, float freq_low, RocalMelScaleFormula mel_formula, int nfilter, bool normalize, float sample_rate); + void init(float freq_high, float freq_low, MelScaleFormula mel_formula, int nfilter, bool normalize, float sample_rate); protected: void create_node() override; diff --git a/rocAL/include/augmentations/audio_augmentations/node_preemphasis_filter.h b/rocAL/include/augmentations/audio_augmentations/node_preemphasis_filter.h index 1ae7aa953..85422829c 100644 --- a/rocAL/include/augmentations/audio_augmentations/node_preemphasis_filter.h +++ b/rocAL/include/augmentations/audio_augmentations/node_preemphasis_filter.h @@ -25,13 +25,12 @@ THE SOFTWARE. #include "pipeline/node.h" #include "parameters/parameter_factory.h" #include "parameters/parameter_vx.h" -#include "rocal_api_types.h" class PreemphasisFilterNode : public Node { public: PreemphasisFilterNode(const std::vector &inputs, const std::vector &outputs); PreemphasisFilterNode() = delete; - void init(FloatParam *preemph_coeff, RocalAudioBorderType preemph_border); + void init(FloatParam *preemph_coeff, AudioBorderType preemph_border); protected: void create_node() override; @@ -40,5 +39,5 @@ class PreemphasisFilterNode : public Node { private: ParameterVX _preemph_coeff; constexpr static float PREEMPH_COEFF_RANGE[2] = {0.97, 0.97}; - RocalAudioBorderType _preemph_border; + AudioBorderType _preemph_border; }; diff --git a/rocAL/include/augmentations/geometry_augmentations/node_crop_resize.h b/rocAL/include/augmentations/geometry_augmentations/node_crop_resize.h index 608723983..ee6b93432 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_crop_resize.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_crop_resize.h @@ -33,10 +33,10 @@ class CropResizeNode : public CropNode { CropResizeNode() = delete; void init(float area, float aspect_ratio, float x_center_drift, float y_center_drift); void init(std::vector& area_factor, std::vector& aspect_ratio, - RocalResizeInterpolationType interpolation_type = RocalResizeInterpolationType::ROCAL_LINEAR_INTERPOLATION); + ResizeInterpolationType interpolation_type = ResizeInterpolationType::LINEAR); void init(FloatParam *area, FloatParam *aspect_ratio, FloatParam *x_drift_factor, FloatParam *y_drift_factor); void init(unsigned int crop_h, unsigned int crop_w, float x_drift, float y_drift, - RocalResizeInterpolationType interpolation_type = RocalResizeInterpolationType::ROCAL_LINEAR_INTERPOLATION); + ResizeInterpolationType interpolation_type = ResizeInterpolationType::LINEAR); unsigned int get_dst_width() { return _outputs[0]->info().max_shape()[0]; } unsigned int get_dst_height() { return _outputs[0]->info().max_shape()[1]; } std::shared_ptr get_crop_param() { return _crop_param; } diff --git a/rocAL/include/augmentations/geometry_augmentations/node_resize.h b/rocAL/include/augmentations/geometry_augmentations/node_resize.h index dbc7bb257..fa8b1a590 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_resize.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_resize.h @@ -22,14 +22,13 @@ THE SOFTWARE. #pragma once #include "pipeline/node.h" -#include "rocal_api_types.h" class ResizeNode : public Node { public: ResizeNode(const std::vector &inputs, const std::vector &outputs); ResizeNode() = delete; - void init(unsigned dest_width, unsigned dest_height, RocalResizeScalingMode scaling_mode, - const std::vector& max_size, RocalResizeInterpolationType interpolation_type); + void init(unsigned dest_width, unsigned dest_height, ResizeScalingMode scaling_mode, + const std::vector& max_size, ResizeInterpolationType interpolation_type); void adjust_out_roi_size(); protected: void create_node() override; @@ -37,7 +36,7 @@ class ResizeNode : public Node { private: vx_array _dst_roi_width , _dst_roi_height; int _interpolation_type; - RocalResizeScalingMode _scaling_mode; + ResizeScalingMode _scaling_mode; unsigned _src_width, _src_height, _dst_width, _dst_height, _out_width, _out_height; unsigned _max_width = 0, _max_height = 0; std::vector _dst_roi_width_vec, _dst_roi_height_vec; diff --git a/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h b/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h index 25f2d3c08..620bf6c0a 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h @@ -32,9 +32,9 @@ class ResizeCropMirrorNode : public CropNode { ResizeCropMirrorNode(const std::vector &inputs, const std::vector &outputs); ResizeCropMirrorNode() = delete; void init(unsigned int crop_h, unsigned int crop_w, IntParam *mirror, - RocalResizeInterpolationType interpolation_type = RocalResizeInterpolationType::ROCAL_LINEAR_INTERPOLATION); + ResizeInterpolationType interpolation_type = ResizeInterpolationType::LINEAR); void init(FloatParam *crop_h_factor, FloatParam *crop_w_factor, IntParam *mirror, - RocalResizeInterpolationType interpolation_type = RocalResizeInterpolationType::ROCAL_LINEAR_INTERPOLATION); + ResizeInterpolationType interpolation_type = ResizeInterpolationType::LINEAR); unsigned int get_dst_width() { return _outputs[0]->info().max_shape()[0]; } unsigned int get_dst_height() { return _outputs[0]->info().max_shape()[1]; } std::shared_ptr get_crop_param() { return _crop_param; } diff --git a/rocAL/include/augmentations/geometry_augmentations/node_resize_mirror_normalize.h b/rocAL/include/augmentations/geometry_augmentations/node_resize_mirror_normalize.h index aaf962fa0..3455475b4 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_resize_mirror_normalize.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_resize_mirror_normalize.h @@ -29,8 +29,8 @@ class ResizeMirrorNormalizeNode : public Node { public: ResizeMirrorNormalizeNode(const std::vector &inputs, const std::vector &outputs); ResizeMirrorNormalizeNode() = delete; - void init(unsigned dest_width, unsigned dest_height, RocalResizeScalingMode scaling_mode, std::vector max_size, - RocalResizeInterpolationType interpolation_type, std::vector &mean, std::vector &std_dev, IntParam *mirror); + void init(unsigned dest_width, unsigned dest_height, ResizeScalingMode scaling_mode, std::vector max_size, + ResizeInterpolationType interpolation_type, std::vector &mean, std::vector &std_dev, IntParam *mirror); void adjust_out_roi_size(); vx_array get_mirror() { return _mirror.default_array(); } @@ -44,7 +44,7 @@ class ResizeMirrorNormalizeNode : public Node { int _interpolation_type; ParameterVX _mirror; constexpr static int _mirror_range[2] = {0, 1}; - RocalResizeScalingMode _scaling_mode; + ResizeScalingMode _scaling_mode; unsigned _src_width, _src_height, _dst_width, _dst_height, _out_width, _out_height; unsigned _max_width = 0, _max_height = 0; std::vector _dst_roi_width_vec, _dst_roi_height_vec; diff --git a/rocAL/include/augmentations/geometry_augmentations/node_rotate.h b/rocAL/include/augmentations/geometry_augmentations/node_rotate.h index 11175a4d4..95adae862 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_rotate.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_rotate.h @@ -25,14 +25,13 @@ THE SOFTWARE. #include "pipeline/node.h" #include "parameters/parameter_factory.h" #include "parameters/parameter_vx.h" -#include "rocal_api_types.h" class RotateNode : public Node { public: RotateNode(const std::vector &inputs, const std::vector &outputs); RotateNode() = delete; - void init(float angle, RocalResizeInterpolationType interpolation_type = ROCAL_LINEAR_INTERPOLATION); - void init(FloatParam *angle_param, RocalResizeInterpolationType interpolation_type = ROCAL_LINEAR_INTERPOLATION); + void init(float angle, ResizeInterpolationType interpolation_type = ResizeInterpolationType::LINEAR); + void init(FloatParam *angle_param, ResizeInterpolationType interpolation_type = ResizeInterpolationType::LINEAR); unsigned int get_dst_width() { return _outputs[0]->info().max_shape()[0]; } unsigned int get_dst_height() { return _outputs[0]->info().max_shape()[1]; } vx_array get_angle() { return _angle.default_array(); } diff --git a/rocAL/include/augmentations/geometry_augmentations/node_slice.h b/rocAL/include/augmentations/geometry_augmentations/node_slice.h index af4ee130a..00e754bfd 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_slice.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_slice.h @@ -25,13 +25,12 @@ THE SOFTWARE. #include "pipeline/node.h" #include "parameters/parameter_factory.h" #include "parameters/parameter_vx.h" -#include "rocal_api_types.h" class SliceNode : public Node { public: SliceNode(const std::vector &inputs, const std::vector &outputs); SliceNode() = delete; - void init(Tensor *anchor_param, Tensor *shape_param, std::vector &fill_values_param, RocalOutOfBoundsPolicy policy); + void init(Tensor *anchor_param, Tensor *shape_param, std::vector &fill_values_param, OutOfBoundsPolicy policy); protected: void create_node() override; @@ -40,5 +39,5 @@ class SliceNode : public Node { private: Tensor *_anchor, *_shape; std::vector _fill_values, _fill_values_vec; - RocalOutOfBoundsPolicy _policy = RocalOutOfBoundsPolicy::ROCAL_ERROR; + OutOfBoundsPolicy _policy = OutOfBoundsPolicy::ERROR; }; diff --git a/rocAL/include/augmentations/geometry_augmentations/node_warp_affine.h b/rocAL/include/augmentations/geometry_augmentations/node_warp_affine.h index a6581e399..69f642597 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_warp_affine.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_warp_affine.h @@ -30,9 +30,9 @@ class WarpAffineNode : public Node { public: WarpAffineNode(const std::vector &inputs, const std::vector &outputs); WarpAffineNode() = delete; - void init(float x0, float x1, float y0, float y1, float o0, float o1, RocalResizeInterpolationType interpolation_type); + void init(float x0, float x1, float y0, float y1, float o0, float o1, ResizeInterpolationType interpolation_type); void init(FloatParam *x0, FloatParam *x1, FloatParam *y0, FloatParam *y1, - FloatParam *o0, FloatParam *o1, RocalResizeInterpolationType interpolation_type); + FloatParam *o0, FloatParam *o1, ResizeInterpolationType interpolation_type); protected: void create_node() override; diff --git a/rocAL/include/pipeline/commons.h b/rocAL/include/pipeline/commons.h index f405db354..7fb9c3ffc 100644 --- a/rocAL/include/pipeline/commons.h +++ b/rocAL/include/pipeline/commons.h @@ -215,4 +215,53 @@ enum MissingComponentsBehaviour { MISSING_COMPONENT_ERROR = 0, MISSING_COMPONENT_SKIP, MISSING_COMPONENT_EMPTY -}; \ No newline at end of file +}; + +/*! \brief Internal Resize Scaling Mode enum + * Internal version of RocalResizeScalingMode for use within rocAL implementation + */ +enum class ResizeScalingMode { + DEFAULT = 0, + STRETCH, + NOT_SMALLER, + NOT_LARGER, + MIN_MAX +}; + +/*! \brief Internal Resize Interpolation Type enum + * Internal version of RocalResizeInterpolationType for use within rocAL implementation + */ +enum class ResizeInterpolationType { + NEAREST_NEIGHBOR = 0, + LINEAR, + CUBIC, + LANCZOS, + GAUSSIAN, + TRIANGULAR +}; + +/*! \brief Internal Mel Scale Formula enum + * Internal version of RocalMelScaleFormula for use within rocAL implementation + */ +enum class MelScaleFormula { + SLANEY = 0, + HTK +}; + +/*! \brief Internal Audio Border Type enum + * Internal version of RocalAudioBorderType for use within rocAL implementation + */ +enum class AudioBorderType { + ZERO = 0, + CLAMP, + REFLECT +}; + +/*! \brief Internal Out Of Bounds Policy enum + * Internal version of RocalOutOfBoundsPolicy for use within rocAL implementation + */ +enum class OutOfBoundsPolicy { + PAD = 0, + TRIMTOSHAPE, + ERROR +}; diff --git a/rocAL/source/api/rocal_api_augmentation.cpp b/rocAL/source/api/rocal_api_augmentation.cpp index 09340ebe6..fdce0f00a 100644 --- a/rocAL/source/api/rocal_api_augmentation.cpp +++ b/rocAL/source/api/rocal_api_augmentation.cpp @@ -86,7 +86,7 @@ rocalRotate( output_info.modify_dims_width_and_height(op_tensor_layout, dest_width, dest_height); output = context->master_graph->create_tensor(output_info, is_output); std::shared_ptr rotate_node = context->master_graph->add_node({input}, {output}); - rotate_node->init(angle, interpolation_type); + rotate_node->init(angle, static_cast(interpolation_type)); if (context->master_graph->meta_data_graph()) context->master_graph->meta_add_node(rotate_node); } catch (const std::exception& e) { @@ -126,7 +126,7 @@ rocalRotateFixed( output = context->master_graph->create_tensor(output_info, is_output); std::shared_ptr rotate_node = context->master_graph->add_node({input}, {output}); - rotate_node->init(angle, interpolation_type); + rotate_node->init(angle, static_cast(interpolation_type)); if (context->master_graph->meta_data_graph()) context->master_graph->meta_add_node(rotate_node); } catch (const std::exception& e) { @@ -376,7 +376,7 @@ rocalRandomResizedCrop( output = context->master_graph->create_tensor(output_info, is_output); std::shared_ptr random_resize_crop_node = context->master_graph->add_node({input}, {output}); - random_resize_crop_node->init(area_factor, aspect_ratio, interpolation_type); + random_resize_crop_node->init(area_factor, aspect_ratio, static_cast(interpolation_type)); if (context->master_graph->meta_data_graph()) context->master_graph->meta_add_node(random_resize_crop_node); } catch (const std::exception& e) { @@ -458,7 +458,7 @@ rocalROIResize( output = context->master_graph->create_tensor(output_info, is_output); std::shared_ptr roi_resize_node = context->master_graph->add_node({input}, {output}); - roi_resize_node->init(roi_h, roi_w, roi_pos_x, roi_pos_y, interpolation_type); + roi_resize_node->init(roi_h, roi_w, roi_pos_x, roi_pos_y, static_cast(interpolation_type)); if (context->master_graph->meta_data_graph()) context->master_graph->meta_add_node(roi_resize_node); } catch (const std::exception& e) { @@ -554,7 +554,7 @@ rocalResize( output = context->master_graph->create_tensor(output_info, is_output); std::shared_ptr resize_node = context->master_graph->add_node({input}, {output}); - resize_node->init(out_width, out_height, resize_scaling_mode, maximum_size, interpolation_type); + resize_node->init(out_width, out_height, static_cast(resize_scaling_mode), maximum_size, static_cast(interpolation_type)); if (context->master_graph->meta_data_graph()) context->master_graph->meta_add_node(resize_node); } catch (const std::exception& e) { @@ -666,7 +666,7 @@ RocalTensor ROCAL_API_CALL output = context->master_graph->create_tensor(output_info, is_output); std::shared_ptr rmn_node = context->master_graph->add_node({input}, {output}); - rmn_node->init(out_width, out_height, resize_scaling_mode, maximum_size, interpolation_type, mean, std_dev, mirror); + rmn_node->init(out_width, out_height, static_cast(resize_scaling_mode), maximum_size, static_cast(interpolation_type), mean, std_dev, mirror); if (context->master_graph->meta_data_graph()) context->master_graph->meta_add_node(rmn_node); } catch (const std::exception& e) { @@ -860,7 +860,7 @@ rocalWarpAffine( output_info.modify_dims_width_and_height(op_tensor_layout, dest_width, dest_height); output = context->master_graph->create_tensor(output_info, is_output); - context->master_graph->add_node({input}, {output})->init(x0, x1, y0, y1, o0, o1, interpolation_type); + context->master_graph->add_node({input}, {output})->init(x0, x1, y0, y1, o0, o1, static_cast(interpolation_type)); } catch (const std::exception& e) { ROCAL_PRINT_EXCEPTION(context, e); } @@ -899,7 +899,7 @@ rocalWarpAffineFixed( output_info.modify_dims_width_and_height(op_tensor_layout, dest_width, dest_height); output = context->master_graph->create_tensor(output_info, is_output); - context->master_graph->add_node({input}, {output})->init(x0, x1, y0, y1, o0, o1, interpolation_type); + context->master_graph->add_node({input}, {output})->init(x0, x1, y0, y1, o0, o1, static_cast(interpolation_type)); } catch (const std::exception& e) { ROCAL_PRINT_EXCEPTION(context, e); } @@ -2015,7 +2015,7 @@ rocalPreEmphasisFilter(RocalContext p_context, TensorInfo output_info = input->info(); output_info.set_data_type(op_tensor_datatype); output = context->master_graph->create_tensor(output_info, is_output); - context->master_graph->add_node({input}, {output})->init(preemph_coeff, preemph_border_type); + context->master_graph->add_node({input}, {output})->init(preemph_coeff, static_cast(preemph_border_type)); } catch (const std::exception& e) { ROCAL_PRINT_EXCEPTION(context, e); } @@ -2315,7 +2315,7 @@ rocalSlice( output_info.set_data_type(op_tensor_data_type); output_info.set_max_shape(); output = context->master_graph->create_tensor(output_info, is_output); - context->master_graph->add_node({input}, {output})->init(anchor, shape, fill_values, policy); + context->master_graph->add_node({input}, {output})->init(anchor, shape, fill_values, static_cast(policy)); } catch (const std::exception& e) { ROCAL_PRINT_EXCEPTION(context, e); } @@ -2376,7 +2376,7 @@ rocalMelFilterBank( output_info.set_dims(dims); output_info.set_data_type(op_tensor_data_type); output = context->master_graph->create_tensor(output_info, is_output); - context->master_graph->add_node({input}, {output})->init(freq_high, freq_low, mel_formula, nfilter, normalize, sample_rate); + context->master_graph->add_node({input}, {output})->init(freq_high, freq_low, static_cast(mel_formula), nfilter, normalize, sample_rate); } catch (const std::exception& e) { ROCAL_PRINT_EXCEPTION(context, e); } diff --git a/rocAL/source/api/rocal_api_data_loaders.cpp b/rocAL/source/api/rocal_api_data_loaders.cpp index 08979d3d2..32e32e7a4 100644 --- a/rocAL/source/api/rocal_api_data_loaders.cpp +++ b/rocAL/source/api/rocal_api_data_loaders.cpp @@ -1913,7 +1913,7 @@ rocalVideoFileResize( resize_output->reset_tensor_roi(); std::shared_ptr resize_node = context->master_graph->add_node({output}, {resize_output}); - resize_node->init(out_width, out_height, resize_scaling_mode, maximum_size, interpolation_type); + resize_node->init(out_width, out_height, static_cast(resize_scaling_mode), maximum_size, static_cast(interpolation_type)); if (is_output) { auto actual_output = context->master_graph->create_tensor(output_info, is_output); @@ -2062,7 +2062,7 @@ rocalVideoFileResizeSingleShard( resize_output->reset_tensor_roi(); std::shared_ptr resize_node = context->master_graph->add_node({output}, {resize_output}); - resize_node->init(out_width, out_height, resize_scaling_mode, maximum_size, interpolation_type); + resize_node->init(out_width, out_height, static_cast(resize_scaling_mode), maximum_size, static_cast(interpolation_type)); if (is_output) { auto actual_output = context->master_graph->create_tensor(output_info, is_output); diff --git a/rocAL/source/augmentations/audio_augmentations/node_mel_filter_bank.cpp b/rocAL/source/augmentations/audio_augmentations/node_mel_filter_bank.cpp index d3bc4e79e..a3a056831 100644 --- a/rocAL/source/augmentations/audio_augmentations/node_mel_filter_bank.cpp +++ b/rocAL/source/augmentations/audio_augmentations/node_mel_filter_bank.cpp @@ -52,7 +52,7 @@ void MelFilterBankNode::create_node() { void MelFilterBankNode::update_node() {} -void MelFilterBankNode::init(float freq_high, float freq_low, RocalMelScaleFormula mel_formula, +void MelFilterBankNode::init(float freq_high, float freq_low, MelScaleFormula mel_formula, int nfilter, bool normalize, float sample_rate) { _freq_high = freq_high; _freq_low = freq_low; diff --git a/rocAL/source/augmentations/audio_augmentations/node_preemphasis_filter.cpp b/rocAL/source/augmentations/audio_augmentations/node_preemphasis_filter.cpp index 6f6c19cd9..4576afb44 100644 --- a/rocAL/source/augmentations/audio_augmentations/node_preemphasis_filter.cpp +++ b/rocAL/source/augmentations/audio_augmentations/node_preemphasis_filter.cpp @@ -42,7 +42,7 @@ void PreemphasisFilterNode::update_node() { _preemph_coeff.update_array(); } -void PreemphasisFilterNode::init(FloatParam *preemph_coeff, RocalAudioBorderType preemph_border) { +void PreemphasisFilterNode::init(FloatParam *preemph_coeff, AudioBorderType preemph_border) { if (preemph_coeff == nullptr) ERR("Invalid pre-Emphasis co-efficient passed") _preemph_coeff.set_param(core(preemph_coeff)); diff --git a/rocAL/source/augmentations/geometry_augmentations/node_crop_resize.cpp b/rocAL/source/augmentations/geometry_augmentations/node_crop_resize.cpp index c622fbbd5..5d11cd592 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_crop_resize.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_crop_resize.cpp @@ -94,14 +94,14 @@ void CropResizeNode::init(FloatParam *area, FloatParam *aspect_ratio, FloatParam _crop_param->set_y_drift_factor(core(y_center_drift)); } -void CropResizeNode::init(std::vector& area_factor, std::vector& aspect_ratio, RocalResizeInterpolationType interpolation_type) { +void CropResizeNode::init(std::vector& area_factor, std::vector& aspect_ratio, ResizeInterpolationType interpolation_type) { auto aspect_ratio_range = std::make_pair((float)aspect_ratio[0], (float)aspect_ratio[1]); auto area_factor_range = std::make_pair((float)area_factor[0], (float)area_factor[1]); _crop_param = std::make_shared(aspect_ratio_range, area_factor_range, NUM_ATTEMPTS, _batch_size); _interpolation_type = static_cast(interpolation_type); } -void CropResizeNode::init(unsigned int crop_h, unsigned int crop_w, float x_drift, float y_drift, RocalResizeInterpolationType interpolation_type) { +void CropResizeNode::init(unsigned int crop_h, unsigned int crop_w, float x_drift, float y_drift, ResizeInterpolationType interpolation_type) { _crop_param = std::make_shared(_batch_size); _crop_param->crop_w = crop_w; _crop_param->crop_h = crop_h; diff --git a/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp b/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp index a87357255..10d16307f 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp @@ -83,10 +83,10 @@ void ResizeNode::update_node() { _dst_roi_height_vec.clear(); } -void ResizeNode::init(unsigned dest_width, unsigned dest_height, RocalResizeScalingMode scaling_mode, - const std::vector &max_size, RocalResizeInterpolationType interpolation_type) { +void ResizeNode::init(unsigned dest_width, unsigned dest_height, ResizeScalingMode scaling_mode, + const std::vector &max_size, ResizeInterpolationType interpolation_type) { _interpolation_type = (int)interpolation_type; - _scaling_mode = scaling_mode; + _scaling_mode = static_cast(scaling_mode); _out_width = dest_width; _out_height = dest_height; if (max_size.size() > 0) { @@ -98,7 +98,7 @@ void ResizeNode::init(unsigned dest_width, unsigned dest_height, RocalResizeScal void ResizeNode::adjust_out_roi_size() { bool has_max_size = (_max_width | _max_height) > 0; - if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_STRETCH) { + if (_scaling_mode == ResizeScalingMode::STRETCH) { if (!_dst_width) _dst_width = _src_width; if (!_dst_height) _dst_height = _src_height; @@ -106,7 +106,7 @@ void ResizeNode::adjust_out_roi_size() { if (_max_width) _dst_width = std::min(_dst_width, _max_width); if (_max_height) _dst_height = std::min(_dst_height, _max_height); } - } else if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_DEFAULT) { + } else if (_scaling_mode == ResizeScalingMode::DEFAULT) { if ((!_dst_width) & _dst_height) { // Only height is passed _dst_width = std::lround(_src_width * (static_cast(_dst_height) / _src_height)); } else if ((!_dst_height) & _dst_width) { // Only width is passed @@ -121,9 +121,9 @@ void ResizeNode::adjust_out_roi_size() { float scale = 1.0f; float scale_w = static_cast(_dst_width) / _src_width; float scale_h = static_cast(_dst_height) / _src_height; - if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_NOT_SMALLER) { + if (_scaling_mode == ResizeScalingMode::NOT_SMALLER) { scale = std::max(scale_w, scale_h); - } else if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_NOT_LARGER) { + } else if (_scaling_mode == ResizeScalingMode::NOT_LARGER) { scale = (scale_w > 0 && scale_h > 0) ? std::min(scale_w, scale_h) : ((scale_w > 0) ? scale_w : scale_h); } diff --git a/rocAL/source/augmentations/geometry_augmentations/node_resize_crop_mirror.cpp b/rocAL/source/augmentations/geometry_augmentations/node_resize_crop_mirror.cpp index 4730a9016..05094ce51 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_resize_crop_mirror.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_resize_crop_mirror.cpp @@ -83,7 +83,7 @@ void ResizeCropMirrorNode::update_node() { } } -void ResizeCropMirrorNode::init(unsigned int crop_h, unsigned int crop_w, IntParam *mirror, RocalResizeInterpolationType interpolation_type) { +void ResizeCropMirrorNode::init(unsigned int crop_h, unsigned int crop_w, IntParam *mirror, ResizeInterpolationType interpolation_type) { _crop_param->crop_w = crop_w; _crop_param->crop_h = crop_h; _crop_param->x1 = 0; @@ -92,7 +92,7 @@ void ResizeCropMirrorNode::init(unsigned int crop_h, unsigned int crop_w, IntPar _interpolation_type = static_cast(interpolation_type); } -void ResizeCropMirrorNode::init(FloatParam *crop_h_factor, FloatParam *crop_w_factor, IntParam *mirror, RocalResizeInterpolationType interpolation_type) { +void ResizeCropMirrorNode::init(FloatParam *crop_h_factor, FloatParam *crop_w_factor, IntParam *mirror, ResizeInterpolationType interpolation_type) { _crop_param->set_crop_height_factor(core(crop_h_factor)); _crop_param->set_crop_width_factor(core(crop_w_factor)); _crop_param->set_random(); diff --git a/rocAL/source/augmentations/geometry_augmentations/node_resize_mirror_normalize.cpp b/rocAL/source/augmentations/geometry_augmentations/node_resize_mirror_normalize.cpp index 19c0ff031..127c94784 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_resize_mirror_normalize.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_resize_mirror_normalize.cpp @@ -117,8 +117,8 @@ void ResizeMirrorNormalizeNode::update_node() { _dst_roi_height_vec.clear(); _mirror.update_array(); } -void ResizeMirrorNormalizeNode::init(unsigned dest_width, unsigned dest_height, RocalResizeScalingMode scaling_mode, std::vector max_size, - RocalResizeInterpolationType interpolation_type, std::vector &mean, std::vector &std_dev, IntParam *mirror) { +void ResizeMirrorNormalizeNode::init(unsigned dest_width, unsigned dest_height, ResizeScalingMode scaling_mode, std::vector max_size, + ResizeInterpolationType interpolation_type, std::vector &mean, std::vector &std_dev, IntParam *mirror) { _interpolation_type = static_cast(interpolation_type); _scaling_mode = scaling_mode; _out_width = dest_width; @@ -135,7 +135,7 @@ void ResizeMirrorNormalizeNode::init(unsigned dest_width, unsigned dest_height, void ResizeMirrorNormalizeNode::adjust_out_roi_size() { bool has_max_size = (_max_width | _max_height) > 0; - if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_MIN_MAX) { + if (_scaling_mode == ResizeScalingMode::MIN_MAX) { // Min size and max size used for MLPerf MaskRCNN resize augmentation unsigned min_size = _max_width; unsigned max_size = _max_height; @@ -158,7 +158,7 @@ void ResizeMirrorNormalizeNode::adjust_out_roi_size() { _dst_height = size; _dst_width = static_cast(size * _src_width / _src_height); } - } else if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_STRETCH) { + } else if (_scaling_mode == ResizeScalingMode::STRETCH) { if (_dst_width == 0) _dst_width = _src_width; if (_dst_height == 0) _dst_height = _src_height; @@ -166,7 +166,7 @@ void ResizeMirrorNormalizeNode::adjust_out_roi_size() { if (_max_width != 0) _dst_width = std::min(_dst_width, _max_width); if (_max_height != 0) _dst_height = std::min(_dst_height, _max_height); } - } else if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_DEFAULT) { + } else if (_scaling_mode == ResizeScalingMode::DEFAULT) { if (_dst_width == 0 && _dst_height != 0) { // Only height is passed _dst_width = std::lround(_src_width * (static_cast(_dst_height) / _src_height)); } else if (_dst_height == 0 && _dst_width != 0) { // Only width is passed @@ -181,9 +181,9 @@ void ResizeMirrorNormalizeNode::adjust_out_roi_size() { float scale = 1.0f; float scale_w = static_cast(_dst_width) / _src_width; float scale_h = static_cast(_dst_height) / _src_height; - if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_NOT_SMALLER) { + if (_scaling_mode == ResizeScalingMode::NOT_SMALLER) { scale = std::max(scale_w, scale_h); - } else if (_scaling_mode == RocalResizeScalingMode::ROCAL_SCALING_MODE_NOT_LARGER) { + } else if (_scaling_mode == ResizeScalingMode::NOT_LARGER) { scale = (scale_w > 0 && scale_h > 0) ? std::min(scale_w, scale_h) : ((scale_w > 0) ? scale_w : scale_h); } diff --git a/rocAL/source/augmentations/geometry_augmentations/node_rotate.cpp b/rocAL/source/augmentations/geometry_augmentations/node_rotate.cpp index 6d7177ad9..92f269978 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_rotate.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_rotate.cpp @@ -47,12 +47,12 @@ void RotateNode::create_node() { THROW("Adding the rotate (vxExtRppRotate) node failed: " + TOSTR(status)) } -void RotateNode::init(float angle, RocalResizeInterpolationType interpolation_type) { +void RotateNode::init(float angle, ResizeInterpolationType interpolation_type) { _angle.set_param(angle); _interpolation_type = static_cast(interpolation_type); } -void RotateNode::init(FloatParam *angle, RocalResizeInterpolationType interpolation_type) { +void RotateNode::init(FloatParam *angle, ResizeInterpolationType interpolation_type) { _angle.set_param(core(angle)); _interpolation_type = static_cast(interpolation_type); } diff --git a/rocAL/source/augmentations/geometry_augmentations/node_slice.cpp b/rocAL/source/augmentations/geometry_augmentations/node_slice.cpp index bd5e15ed5..f650f19db 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_slice.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_slice.cpp @@ -51,7 +51,7 @@ void SliceNode::create_node() { void SliceNode::update_node() {} -void SliceNode::init(Tensor *anchor, Tensor *shape, std::vector &fill_values, RocalOutOfBoundsPolicy policy) { +void SliceNode::init(Tensor *anchor, Tensor *shape, std::vector &fill_values, OutOfBoundsPolicy policy) { _policy = policy; _anchor = anchor; _shape = shape; diff --git a/rocAL/source/augmentations/geometry_augmentations/node_warp_affine.cpp b/rocAL/source/augmentations/geometry_augmentations/node_warp_affine.cpp index 09f3d7f68..90aeb2c7e 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_warp_affine.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_warp_affine.cpp @@ -79,7 +79,7 @@ void WarpAffineNode::update_affine_array() { THROW(" vxCopyArrayRange failed in the WarpAffine(vxExtRppWarpAffinePD) node: " + TOSTR(affine_status)) } -void WarpAffineNode::init(float x0, float x1, float y0, float y1, float o0, float o1, RocalResizeInterpolationType interpolation_type) { +void WarpAffineNode::init(float x0, float x1, float y0, float y1, float o0, float o1, ResizeInterpolationType interpolation_type) { _x0.set_param(x0); _x1.set_param(x1); _y0.set_param(y0); @@ -90,7 +90,7 @@ void WarpAffineNode::init(float x0, float x1, float y0, float y1, float o0, floa } void WarpAffineNode::init(FloatParam* x0, FloatParam* x1, FloatParam* y0, FloatParam* y1, - FloatParam* o0, FloatParam* o1, RocalResizeInterpolationType interpolation_type) { + FloatParam* o0, FloatParam* o1, ResizeInterpolationType interpolation_type) { _x0.set_param(core(x0)); _x1.set_param(core(x1)); _y0.set_param(core(y0)); From 22af55b6ffd67c28964793e87ae20b1c539db5c5 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Mon, 22 Sep 2025 02:30:53 -0500 Subject: [PATCH 002/118] Remove unused include rocal_api_types.h --- .../include/augmentations/arithmetic_augmentations/node_log1p.h | 1 - .../arithmetic_augmentations/node_tensor_add_tensor.h | 1 - .../arithmetic_augmentations/node_tensor_mul_scalar.h | 1 - rocAL/include/augmentations/audio_augmentations/node_resample.h | 1 - .../include/augmentations/audio_augmentations/node_spectrogram.h | 1 - .../geometry_augmentations/node_resize_crop_mirror.h | 1 - 6 files changed, 6 deletions(-) diff --git a/rocAL/include/augmentations/arithmetic_augmentations/node_log1p.h b/rocAL/include/augmentations/arithmetic_augmentations/node_log1p.h index c7ec20cd6..d6adb7d2e 100644 --- a/rocAL/include/augmentations/arithmetic_augmentations/node_log1p.h +++ b/rocAL/include/augmentations/arithmetic_augmentations/node_log1p.h @@ -23,7 +23,6 @@ THE SOFTWARE. #pragma once #include "pipeline/graph.h" #include "pipeline/node.h" -#include "rocal_api_types.h" class Log1pNode : public Node { public: diff --git a/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_add_tensor.h b/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_add_tensor.h index 863630e0a..f8926ece5 100644 --- a/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_add_tensor.h +++ b/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_add_tensor.h @@ -23,7 +23,6 @@ THE SOFTWARE. #pragma once #include "pipeline/graph.h" #include "pipeline/node.h" -#include "rocal_api_types.h" class TensorAddTensorNode : public Node { public: diff --git a/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_mul_scalar.h b/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_mul_scalar.h index ad4cadbfa..dee4890ae 100644 --- a/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_mul_scalar.h +++ b/rocAL/include/augmentations/arithmetic_augmentations/node_tensor_mul_scalar.h @@ -23,7 +23,6 @@ THE SOFTWARE. #pragma once #include "pipeline/graph.h" #include "pipeline/node.h" -#include "rocal_api_types.h" class TensorMulScalarNode : public Node { public: diff --git a/rocAL/include/augmentations/audio_augmentations/node_resample.h b/rocAL/include/augmentations/audio_augmentations/node_resample.h index 0e0582187..37f915254 100644 --- a/rocAL/include/augmentations/audio_augmentations/node_resample.h +++ b/rocAL/include/augmentations/audio_augmentations/node_resample.h @@ -23,7 +23,6 @@ THE SOFTWARE. #pragma once #include "pipeline/graph.h" #include "pipeline/node.h" -#include "rocal_api_types.h" class ResampleNode : public Node { public: diff --git a/rocAL/include/augmentations/audio_augmentations/node_spectrogram.h b/rocAL/include/augmentations/audio_augmentations/node_spectrogram.h index e0ac8d91e..4d20fc22e 100644 --- a/rocAL/include/augmentations/audio_augmentations/node_spectrogram.h +++ b/rocAL/include/augmentations/audio_augmentations/node_spectrogram.h @@ -23,7 +23,6 @@ THE SOFTWARE. #pragma once #include "pipeline/graph.h" #include "pipeline/node.h" -#include "rocal_api_types.h" /// @brief Generates hann window for spectrogram /// @param output diff --git a/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h b/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h index 620bf6c0a..6f633ae8d 100644 --- a/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h +++ b/rocAL/include/augmentations/geometry_augmentations/node_resize_crop_mirror.h @@ -25,7 +25,6 @@ THE SOFTWARE. #include "parameters/parameter_crop_factory.h" #include "parameters/parameter_factory.h" #include "parameters/parameter_vx.h" -#include "rocal_api_types.h" class ResizeCropMirrorNode : public CropNode { public: From 752a734b2bb72e23a0e9e1779d0b3e97f68bb393 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Sep 2025 22:29:04 -0500 Subject: [PATCH 003/118] Introduce EnumRegistry Add support to register all internal enums --- rocAL/include/decoders/image/decoder.h | 1 + rocAL/include/meta_data/meta_data_reader.h | 2 + rocAL/include/pipeline/commons.h | 15 +++ rocAL/include/pipeline/enum_registry.h | 113 +++++++++++++++++++++ rocAL/include/readers/image/image_reader.h | 3 + 5 files changed, 134 insertions(+) create mode 100644 rocAL/include/pipeline/enum_registry.h diff --git a/rocAL/include/decoders/image/decoder.h b/rocAL/include/decoders/image/decoder.h index 5239d3e5c..c283d902f 100644 --- a/rocAL/include/decoders/image/decoder.h +++ b/rocAL/include/decoders/image/decoder.h @@ -45,6 +45,7 @@ enum class DecoderType { ROCJPEG_DEC = 7, //!< rocJpeg hardware decoder for decoding jpeg files ROCJPEG_CROPPED = 8 //!< For partial decoding of jpeg files using rocJpeg hardware decoder }; +AUTO_REGISTER_ENUM(DecoderType) class DecoderConfig { public: diff --git a/rocAL/include/meta_data/meta_data_reader.h b/rocAL/include/meta_data/meta_data_reader.h index ee5c54595..56c2bc00d 100644 --- a/rocAL/include/meta_data/meta_data_reader.h +++ b/rocAL/include/meta_data/meta_data_reader.h @@ -27,6 +27,7 @@ THE SOFTWARE. #include #include #include "meta_data/meta_data.h" +#include "pipeline/enum_registry.h" enum class MetaDataReaderType { FOLDER_BASED_LABEL_READER = 0, // Used for imagenet-like dataset @@ -44,6 +45,7 @@ enum class MetaDataReaderType { MXNET_META_DATA_READER, WEBDATASET_META_DATA_READER }; +AUTO_REGISTER_ENUM(MetaDataReaderType) struct MetaDataConfig { private: diff --git a/rocAL/include/pipeline/commons.h b/rocAL/include/pipeline/commons.h index 7fb9c3ffc..b3750d03a 100644 --- a/rocAL/include/pipeline/commons.h +++ b/rocAL/include/pipeline/commons.h @@ -34,6 +34,7 @@ THE SOFTWARE. #include "pipeline/exception.h" #include "pipeline/log.h" #include "pipeline/filesystem.h" +#include "pipeline/enum_registry.h" // Calculated from the largest resize shorter dimension in imagenet validation dataset #define MAX_ASPECT_RATIO 6.0f @@ -54,6 +55,7 @@ enum class RocalTensorlayout { NCDHW, NONE }; +AUTO_REGISTER_ENUM(RocalTensorlayout) /*! \brief Tensor data type * @@ -68,11 +70,13 @@ enum class RocalTensorDataType { INT32, INT16 }; +AUTO_REGISTER_ENUM(RocalTensorDataType) enum class RocalAffinity { GPU = 0, CPU }; +AUTO_REGISTER_ENUM(RocalAffinity) /*! \brief Color formats currently supported by Rocal SDK as input/output * @@ -83,6 +87,7 @@ enum class RocalColorFormat { U8, RGB_PLANAR, }; +AUTO_REGISTER_ENUM(RocalColorFormat) /*! \brief Memory type, host or device * @@ -93,6 +98,7 @@ enum class RocalMemType { OCL, HIP }; +AUTO_REGISTER_ENUM(RocalMemType) /*! \brief Decoder mode for Video decoding * @@ -102,6 +108,7 @@ enum class DecodeMode { ROCDECODE = 0, CPU }; +AUTO_REGISTER_ENUM(DecodeMode) /*! \brief Tensor ROI type * @@ -111,6 +118,7 @@ enum class RocalROIType { LTRB = 0, XYWH }; +AUTO_REGISTER_ENUM(RocalROIType) /*! \brief Tensor ROI in LTRB format * @@ -173,6 +181,7 @@ enum RocalBatchPolicy { DROP, PARTIAL }; +AUTO_REGISTER_ENUM(RocalBatchPolicy) template class BatchRNG { @@ -216,6 +225,7 @@ enum MissingComponentsBehaviour { MISSING_COMPONENT_SKIP, MISSING_COMPONENT_EMPTY }; +AUTO_REGISTER_ENUM(MissingComponentsBehaviour); /*! \brief Internal Resize Scaling Mode enum * Internal version of RocalResizeScalingMode for use within rocAL implementation @@ -227,6 +237,7 @@ enum class ResizeScalingMode { NOT_LARGER, MIN_MAX }; +AUTO_REGISTER_ENUM(ResizeScalingMode); /*! \brief Internal Resize Interpolation Type enum * Internal version of RocalResizeInterpolationType for use within rocAL implementation @@ -239,6 +250,7 @@ enum class ResizeInterpolationType { GAUSSIAN, TRIANGULAR }; +AUTO_REGISTER_ENUM(ResizeInterpolationType); /*! \brief Internal Mel Scale Formula enum * Internal version of RocalMelScaleFormula for use within rocAL implementation @@ -247,6 +259,7 @@ enum class MelScaleFormula { SLANEY = 0, HTK }; +AUTO_REGISTER_ENUM(MelScaleFormula); /*! \brief Internal Audio Border Type enum * Internal version of RocalAudioBorderType for use within rocAL implementation @@ -256,6 +269,7 @@ enum class AudioBorderType { CLAMP, REFLECT }; +AUTO_REGISTER_ENUM(AudioBorderType); /*! \brief Internal Out Of Bounds Policy enum * Internal version of RocalOutOfBoundsPolicy for use within rocAL implementation @@ -265,3 +279,4 @@ enum class OutOfBoundsPolicy { TRIMTOSHAPE, ERROR }; +AUTO_REGISTER_ENUM(OutOfBoundsPolicy); diff --git a/rocAL/include/pipeline/enum_registry.h b/rocAL/include/pipeline/enum_registry.h new file mode 100644 index 000000000..2736e5851 --- /dev/null +++ b/rocAL/include/pipeline/enum_registry.h @@ -0,0 +1,113 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +/*! + * \brief Centralized enum registry for automatic enum type name management + * + * This singleton class provides a registry for enum types, + * allowing automatic registration and lookup of enum type names. + */ +class EnumRegistry { +public: + /*! + * \brief Get the singleton instance of the enum registry + * \return Reference to the singleton EnumRegistry instance + */ + static EnumRegistry& getInstance() { + static EnumRegistry instance; + return instance; + } + + /*! + * \brief Register an enum type with its string name and conversion function + * \tparam T The enum type to register (must be an enum) + * \param name The string name to associate with the enum type + */ + template + void registerEnum(const std::string& name) { + static_assert(std::is_enum::value, "T must be an enum type"); + _enum_map[std::type_index(typeid(T))] = name; + } + + /*! + * \brief Get the registered name for an enum type + * \tparam T The enum type to look up + * \return The registered string name for the enum type, or empty string if not found + */ + template + std::string getEnumName() const { + static_assert(std::is_enum::value, "T must be an enum type"); + auto it = _enum_map.find(std::type_index(typeid(T))); + return (it != _enum_map.end()) ? it->second : ""; + } + + /*! + * \brief Get the registered name for a type_index + * \param type The type_index to look up + * \return The registered string name, or empty string if not found + */ + std::string getEnumName(const std::type_index& type) const { + auto it = _enum_map.find(type); + return (it != _enum_map.end()) ? it->second : ""; + } + + /*! + * \brief Check if an enum type is registered + * \param type The type_index to check + * \return true if the enum type is registered, false otherwise + */ + bool isEnumRegistered(const std::type_index& type) const { + return _enum_map.find(type) != _enum_map.end(); + } + +private: + EnumRegistry() = default; + ~EnumRegistry() = default; + EnumRegistry(const EnumRegistry&) = delete; + EnumRegistry& operator=(const EnumRegistry&) = delete; + + // Map 1: Type index to string name mapping + std::unordered_map _enum_map; +}; + +/*! + * \brief Macro for automatic enum registration + * \param EnumType The enum type to register + * + * Uses a static variable with lambda function to ensure proper initialization timing. + * Usage: AUTO_REGISTER_ENUM(MyEnumType) + */ +#define AUTO_REGISTER_ENUM(EnumType) \ + static bool enum_registered_##EnumType = []() { \ + EnumRegistry::getInstance().registerEnum(#EnumType); \ + return true; \ + }(); diff --git a/rocAL/include/readers/image/image_reader.h b/rocAL/include/readers/image/image_reader.h index bf0cfdb02..61071eb00 100644 --- a/rocAL/include/readers/image/image_reader.h +++ b/rocAL/include/readers/image/image_reader.h @@ -30,6 +30,7 @@ THE SOFTWARE. #include "meta_data/meta_data_reader.h" #include "readers/video/video_properties.h" #include "pipeline/tensor.h" +#include "pipeline/enum_registry.h" #define CHECK_LMDB_RETURN_STATUS(status) \ do { \ @@ -52,6 +53,7 @@ enum class StorageType { WEBDATASET_RECORDS = 10, // tar files - webdataset format NUMPY_DATA = 11 // to support reading from numpy files }; +AUTO_REGISTER_ENUM(StorageType) enum class ExternalSourceFileMode { FILENAME = 0, @@ -59,6 +61,7 @@ enum class ExternalSourceFileMode { RAWDATA_UNCOMPRESSED = 2, NONE = 3, }; +AUTO_REGISTER_ENUM(ExternalSourceFileMode); struct ShardingInfo { RocalBatchPolicy last_batch_policy; From 6d456382fca60392e0cc00bd97eaa7cb1826f391 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Sep 2025 23:07:45 -0500 Subject: [PATCH 004/118] Introduce Argument class Creates an argument instance for each arg passed in the Node Handles different argument types i.e parameters, vectors, enums and predefined types --- rocAL/include/pipeline/argument.h | 177 ++++++++++++++++++++++++ rocAL/include/pipeline/argument_types.h | 113 +++++++++++++++ rocAL/include/pipeline/node.h | 4 + 3 files changed, 294 insertions(+) create mode 100644 rocAL/include/pipeline/argument.h create mode 100644 rocAL/include/pipeline/argument_types.h diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h new file mode 100644 index 000000000..450507a6d --- /dev/null +++ b/rocAL/include/pipeline/argument.h @@ -0,0 +1,177 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pipeline/argument_types.h" +#include "pipeline/enum_registry.h" +#include "parameters/parameter_factory.h" +#include "pipeline/commons.h" + +/** + * @brief Argument class stores the details of each argument in the Node + * + * This class encapsulates argument information for pipeline nodes, supporting + * various data types including basic types, enums, vectors, maps, and parameters. + */ +class Argument { + public: + std::string arg_name; ///< Name of the argument + std::string type_name; ///< Denotes the data type of the argument + std::string enum_type_name; ///< Denotes the name of the enum + bool is_vector = false; ///< True if the argument contains vector data + bool is_parameter = false; ///< True if the argument is a parameter object + bool is_null_ptr = false; ///< True if the argument represents a null pointer + std::vector values; ///< Storage for argument values (can change to std::variant later) + pParam param; ///< Parameter stored for parameter-type arguments + + private: + // Helper method to get type name from registry or built-in types + template + std::string getTypeName() const { + using DecayedType = std::decay_t; + + if constexpr (std::is_enum_v) { + // For enum types, check the registry first + std::string enum_name = EnumRegistry::getInstance().getEnumName(); + return enum_name.empty() ? "unknown_enum" : enum_name; + } else { + // Use the type name resolution from argument_types.h + return std::string(get_type_name()); + } + } + +public: + + template + explicit inline Argument(const std::string name, T&& val) + : arg_name(std::move(name)) { + if constexpr (std::is_enum_v>) { + type_name = "enum"; // Enum types are stored as integers by default + + enum_type_name = getTypeName(); + if (enum_type_name != "unknown_enum") { + values.push_back(static_cast(val)); + } else { + THROW("Unknown enum type for argument " + arg_name) + } + } else if constexpr (is_vector_type_v>) { + using ElementType = typename std::decay_t::value_type; + std::string element_type_name = getTypeName(); + if (element_type_name != "unknown") { + type_name = element_type_name; + is_vector = true; + values.reserve(val.size()); // Pre-allocate for better performance + for (auto&& v : std::forward(val)) { + values.push_back(static_cast(std::forward(v))); + } + } else { + THROW("Unknown vector element type for argument " + arg_name) + } + } else { + type_name = getTypeName(); + if (type_name != "unknown") { + if constexpr (std::is_same_v, const char*>) { + values.push_back(std::string(val)); + } else { + values.push_back(static_cast>(std::forward(val))); + } + } else { + THROW("Unknown type " + std::string(typeid(T).name()) + " for argument " + arg_name) + } + } + } + + // Used to store the feature key map + explicit inline Argument(std::string name, std::map val) + : arg_name(std::move(name)) { + type_name = "map_string"; + is_vector = true; + if (!val.empty()) { + values.reserve(val.size() * 2); // Pre-allocate for key-value pairs + for (auto&& pair : std::move(val)) { + values.push_back(std::move(pair.first)); // Push key + values.push_back(std::move(pair.second)); // Push value + } + } + } + + // Used to store the shared_ptr + template + explicit inline Argument(std::string name, std::shared_ptr val) + : arg_name(std::move(name)) { + type_name = "shared_ptr"; + + // For MetadataReader case store an empty value + // During deserialization the MetadataReader should be created and passed from the MasterGraph. + if (arg_name == "meta_data_reader") { + values.push_back(static_cast(0)); + } + // Could store additional shared_ptr metadata here if needed + } + + // Deduces the type of parameter of the argument + inline void extract_param(const RocalParameterType param_type, pParam parameter) { + if (param_type == RocalParameterType::DETERMINISTIC) { + enum_type_name = "SimpleParameter"; + } else if (param_type == RocalParameterType::RANDOM_UNIFORM) { + enum_type_name = "UniformRand"; + } else if (param_type == RocalParameterType::RANDOM_CUSTOM) { + enum_type_name = "CustomRand"; + } + param = parameter; + is_parameter = true; + } + + // Constructor for FloatParam arguments + explicit inline Argument(std::string name, FloatParam* param) + : arg_name(std::move(name)) { + type_name = "float"; + if (param == nullptr) { + is_null_ptr = true; + type_name = "nullptr"; + return; + } + extract_param(param->type, param); + } + + // Constructor for IntParam arguments + explicit inline Argument(std::string name, IntParam* param) + : arg_name(std::move(name)) { + type_name = "int"; + if (param == nullptr) { + type_name = "nullptr"; + is_null_ptr = true; + return; + } + extract_param(param->type, param); + } +}; diff --git a/rocAL/include/pipeline/argument_types.h b/rocAL/include/pipeline/argument_types.h new file mode 100644 index 000000000..6ce1fcd99 --- /dev/null +++ b/rocAL/include/pipeline/argument_types.h @@ -0,0 +1,113 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once +#include +#include +#include +#include +#include +#include + +// Enhanced type traits for argument processing (C++17 compatible) + +// Vector type detection +template +struct is_vector_type : std::false_type {}; + +template +struct is_vector_type> : std::true_type {}; + +template +constexpr bool is_vector_type_v = is_vector_type::value; + +// Map type detection +template +struct is_map_type : std::false_type {}; + +template +struct is_map_type> : std::true_type {}; + +template +constexpr bool is_map_type_v = is_map_type::value; + +// Shared pointer detection +template +struct is_shared_ptr : std::false_type {}; + +template +struct is_shared_ptr> : std::true_type {}; + +template +constexpr bool is_shared_ptr_v = is_shared_ptr::value; + +// String type detection (including const char*) +template +struct is_string_type : std::false_type {}; + +template <> +struct is_string_type : std::true_type {}; + +template <> +struct is_string_type : std::true_type {}; + +template <> +struct is_string_type : std::true_type {}; + +template +constexpr bool is_string_type_v = is_string_type>::value; + +// SFINAE-based type checking (C++17 compatible) +template +using enable_if_basic_type = std::enable_if_t< + std::is_arithmetic_v> || is_string_type_v +>; + +template +using enable_if_enum_type = std::enable_if_t>>; + +template +using enable_if_vector_type = std::enable_if_t>>; + +template +using enable_if_map_type = std::enable_if_t>>; + +template +using enable_if_shared_ptr_type = std::enable_if_t>>; + +// Compile-time type name resolution +template +constexpr const char* get_type_name() noexcept { + using DecayedType = std::decay_t; + + if constexpr (std::is_same_v) return "int"; + else if constexpr (std::is_same_v) return "unsigned"; + else if constexpr (std::is_same_v) return "size_t"; + else if constexpr (std::is_same_v) return "float"; + else if constexpr (std::is_same_v) return "double"; + else if constexpr (std::is_same_v) return "bool"; + else if constexpr (std::is_same_v) return "string"; + else if constexpr (std::is_same_v || std::is_same_v) return "char_str"; + else if constexpr (is_map_type_v) return "map"; + else if constexpr (is_shared_ptr_v) return "shared_ptr"; + else return "unknown"; +} diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index f5ebfccaf..b0d22262e 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -27,6 +27,8 @@ THE SOFTWARE. #include "pipeline/graph.h" #include "meta_data/meta_data_graph.h" #include "pipeline/tensor.h" +#include "argument.h" + class Node { public: Node(const std::vector &inputs, const std::vector &outputs) : _inputs(inputs), @@ -47,6 +49,7 @@ class Node { const Roi2DCords *get_dst_roi() { return _outputs[0]->info().roi().get_2D_roi(); } void set_graph_id(int id) { _graph_id = id; } int get_graph_id() { return _graph_id; } + std::vector get_args_list() { return _args; } protected: virtual void create_node() = 0; @@ -60,4 +63,5 @@ class Node { std::vector> _next; // Stores the reference to a list of next Nodes std::vector> _prev; // Stores the reference to a list of previous Nodes int _graph_id = -1; + std::vector _args; }; From 90736c883ea5e2a59ed24838273d0e09ccf69a08 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Sep 2025 23:26:17 -0500 Subject: [PATCH 005/118] Introduce PipelineOperator class --- rocAL/include/pipeline/pipeline_operator.h | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 rocAL/include/pipeline/pipeline_operator.h diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h new file mode 100644 index 000000000..b5b148e95 --- /dev/null +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -0,0 +1,45 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once + +#include +#include "pipeline/node.h" + +// Stores the information for the operator in the pipeline +class PipelineOperator { + public: + explicit inline PipelineOperator(std::string op_name, std::string op_module_name, + std::shared_ptr op_node = nullptr) { + operator_name = op_name; + module_name = op_module_name; + node = op_node; + } + void set_arguments(std::vector op_arguments) { + arguments = op_arguments; + } + + std::string operator_name; // Name of the Node/operator + std::string module_name; // Denotes the type of operator i.e loader/reader/augmentation + std::vector arguments; + std::shared_ptr node; +}; From fc55deb98088d42afe881300b9712acefc63749b Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Sep 2025 23:27:34 -0500 Subject: [PATCH 006/118] Add support to create and return node name and tensor name --- rocAL/include/pipeline/node.h | 8 +++++++- rocAL/include/pipeline/tensor.h | 4 +++- rocAL/source/pipeline/tensor.cpp | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index b0d22262e..1865f4ec0 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -27,7 +27,7 @@ THE SOFTWARE. #include "pipeline/graph.h" #include "meta_data/meta_data_graph.h" #include "pipeline/tensor.h" -#include "argument.h" +#include "pipeline/argument.h" class Node { public: @@ -49,6 +49,7 @@ class Node { const Roi2DCords *get_dst_roi() { return _outputs[0]->info().roi().get_2D_roi(); } void set_graph_id(int id) { _graph_id = id; } int get_graph_id() { return _graph_id; } + virtual std::string node_name() { return ""; } std::vector get_args_list() { return _args; } protected: @@ -64,4 +65,9 @@ class Node { std::vector> _prev; // Stores the reference to a list of previous Nodes int _graph_id = -1; std::vector _args; + template + void set_node_arguments(std::array& arg_names, std::index_sequence, Args... args) { + // Fold expression to create Argument object for each argument in the node + (this->_args.push_back(Argument(arg_names[Indices], std::forward(args))), ...); + } }; diff --git a/rocAL/include/pipeline/tensor.h b/rocAL/include/pipeline/tensor.h index 49fc534ec..097d2df05 100644 --- a/rocAL/include/pipeline/tensor.h +++ b/rocAL/include/pipeline/tensor.h @@ -378,13 +378,15 @@ class Tensor : public rocalTensor { return (_info.mem_type() == RocalMemType::HOST ? ROCAL_CPU : ROCAL_GPU); } uint64_t data_type_size() override { return _info.data_type_size(); } - + std::string tensor_name() { return _tensor_name; } private: vx_tensor _vx_handle = nullptr; //!< The OpenVX tensor void* _mem_handle = nullptr; //!< Pointer to the tensor's internal buffer (opencl or host) TensorInfo _info; //!< The structure holding the info related to the stored OpenVX tensor vx_context _context = nullptr; vx_tensor _vx_roi_handle = nullptr; //!< The OpenVX tensor for ROI + inline static int _tensor_idx = 0; + std::string _tensor_name; }; /*! \brief Contains a list of rocalTensors */ diff --git a/rocAL/source/pipeline/tensor.cpp b/rocAL/source/pipeline/tensor.cpp index 8f196edbb..9c02cb8bd 100644 --- a/rocAL/source/pipeline/tensor.cpp +++ b/rocAL/source/pipeline/tensor.cpp @@ -289,6 +289,7 @@ Tensor::~Tensor() { Tensor::Tensor(const TensorInfo &tensor_info) : _info(tensor_info) { _info._type = TensorInfo::Type::UNKNOWN; + _tensor_name = "tensor_" + std::to_string(_tensor_idx++); _mem_handle = nullptr; } From 49e7025f96fe06b24edb98bb67e26c3258baa99a Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Sep 2025 23:29:25 -0500 Subject: [PATCH 007/118] Add support in MasterGraph to store details of PipelineOperators --- rocAL/include/pipeline/master_graph.h | 11 +++++++++++ rocAL/source/pipeline/master_graph.cpp | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 39a4221df..06086e3b2 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -52,6 +52,8 @@ THE SOFTWARE. #endif #include "meta_data/randombboxcrop_meta_data_reader.h" #include "rocal_api_types.h" +#include "pipeline/pipeline_operator.h" + #define MAX_STRING_LENGTH 100 #define MAX_OBJECTS 50 // Setting an arbitrary value 50.(Max number of objects/image in COCO dataset is 93) #define BBOX_COUNT 4 @@ -240,6 +242,8 @@ class MasterGraph { BoxEncoderGpu *_box_encoder_gpu = nullptr; #endif TimingDbg _rb_block_if_empty_time, _rb_block_if_full_time; + std::vector> _pipeline_operators; + int _op_idx = 0; }; template @@ -247,6 +251,9 @@ std::shared_ptr MasterGraph::add_node(const std::vector &inputs, co auto node = std::make_shared(inputs, outputs); _nodes.push_back(node); + // Add each opertor to the pipeline operators list + _pipeline_operators.push_back(std::make_shared(node->node_name() + "_" + std::to_string(_op_idx++), "augmentation", node)); + for (auto &input : inputs) { if (_tensor_map.find(input) == _tensor_map.end()) THROW("Input tensor is invalid, cannot be found among output of previously created nodes") @@ -287,6 +294,10 @@ inline std::shared_ptr MasterGraph::add_node(const std::vector< _loader_modules.emplace_back(loader_module); node->set_graph_id(_loaders_count++); _root_nodes.push_back(node); + + // Add each opertor to the pipeline operators list + _pipeline_operators.push_back(std::make_shared(node->node_name() + "_" + std::to_string(_op_idx++), "loader", node)); + for (auto &output : outputs) _tensor_map.insert(std::make_pair(output, node)); diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 68953e08a..8eb902904 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1269,6 +1269,15 @@ TensorListVector* MasterGraph::create_label_reader(const char *source_path, Meta _meta_data_reader = create_meta_data_reader(config, _augmented_meta_data); _meta_data_reader->read_all(source_path); + // Add each opertor to the pipeline operators list + auto reader_op = std::make_shared("LabelReader_" + std::to_string(_op_idx++), "reader"); + + // Add all arguments as part of the operator + reader_op->arguments.push_back(Argument("source_path", source_path)); + reader_op->arguments.push_back(Argument("reader_type", reader_type)); + + _pipeline_operators.push_back(reader_op); + std::vector dims = {1}; auto default_labels_info = TensorInfo(std::move(dims), _mem_type, RocalTensorDataType::INT32); // Create default labels Info default_labels_info.set_metadata(); From 25c9d918e2f89f92a166f60a7cdc9014f1d4b2f2 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Sep 2025 23:30:09 -0500 Subject: [PATCH 008/118] Add support to store the argument details in the node for brightness and ImageLoaderNode --- .../color_augmentations/node_brightness.h | 1 + .../include/loaders/image/node_image_loader.h | 1 + .../color_augmentations/node_brightness.cpp | 8 ++++++++ .../source/loaders/image/node_image_loader.cpp | 18 ++++++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/rocAL/include/augmentations/color_augmentations/node_brightness.h b/rocAL/include/augmentations/color_augmentations/node_brightness.h index 0241a16d0..9e181ee81 100644 --- a/rocAL/include/augmentations/color_augmentations/node_brightness.h +++ b/rocAL/include/augmentations/color_augmentations/node_brightness.h @@ -33,6 +33,7 @@ class BrightnessNode : public Node { void init(float alpha, float beta); void init(FloatParam *alpha_param, FloatParam *beta_param); + std::string node_name() override { return "BrightnessNode"; } protected: void create_node() override; diff --git a/rocAL/include/loaders/image/node_image_loader.h b/rocAL/include/loaders/image/node_image_loader.h index 273622005..48c46757e 100644 --- a/rocAL/include/loaders/image/node_image_loader.h +++ b/rocAL/include/loaders/image/node_image_loader.h @@ -44,6 +44,7 @@ class ImageLoaderNode : public Node { const char *prefix = "", unsigned sequence_length = 0, unsigned step = 0, unsigned stride = 0, ExternalSourceFileMode external_file_mode = ExternalSourceFileMode::NONE, const std::string &index_path = ""); std::shared_ptr get_loader_module(); + std::string node_name() override { return "ImageLoaderNode"; } protected: void create_node() override{}; diff --git a/rocAL/source/augmentations/color_augmentations/node_brightness.cpp b/rocAL/source/augmentations/color_augmentations/node_brightness.cpp index 432e9a584..1cdd35c3b 100644 --- a/rocAL/source/augmentations/color_augmentations/node_brightness.cpp +++ b/rocAL/source/augmentations/color_augmentations/node_brightness.cpp @@ -50,11 +50,19 @@ void BrightnessNode::create_node() { void BrightnessNode::init(float alpha, float beta) { _alpha.set_param(alpha); _beta.set_param(beta); + + // Add all arguments as part of the Node + std::array arg_names = {"alpha", "beta"}; + set_node_arguments(arg_names, std::make_index_sequence{}, alpha, beta); } void BrightnessNode::init(FloatParam *alpha, FloatParam *beta) { _alpha.set_param(core(alpha)); _beta.set_param(core(beta)); + + // Add all arguments as part of the Node + std::array arg_names = {"alpha", "beta"}; + set_node_arguments(arg_names, std::make_index_sequence{}, alpha, beta); } void BrightnessNode::update_node() { diff --git a/rocAL/source/loaders/image/node_image_loader.cpp b/rocAL/source/loaders/image/node_image_loader.cpp index 62c5fe3fe..66d04057c 100644 --- a/rocAL/source/loaders/image/node_image_loader.cpp +++ b/rocAL/source/loaders/image/node_image_loader.cpp @@ -50,6 +50,24 @@ void ImageLoaderNode::init(unsigned internal_shard_count, unsigned cpu_num_threa reader_cfg.set_external_filemode(external_file_mode); reader_cfg.set_index_path(index_path); reader_cfg.set_sharding_info(sharding_info); + + + std::array arg_names = { + "internal_shard_count", "cpu_num_threads", "source_path", + "json_path", "feature_key_map", "storage_type", "decoder_type", + "shuffle", "loop", "load_batch_count", "mem_type","meta_data_reader", "decoder_keep_orig", + "last_batch_policy", "pad_last_batch_repeated", "stick_to_shard", "shard_size", + "file_prefix", "sequence_length", "step", "stride", + "external_file_mode", "index_path" + }; + + set_node_arguments(arg_names, std::make_index_sequence{}, internal_shard_count, + cpu_num_threads, source_path, json_path, feature_key_map, storage_type, + decoder_type, shuffle, loop, load_batch_count, mem_type, meta_data_reader, decoder_keep_orig, + sharding_info.last_batch_policy, sharding_info.pad_last_batch_repeated, + sharding_info.stick_to_shard, sharding_info.shard_size, file_prefix, + sequence_length, step, stride, external_file_mode, index_path); + _loader_module->initialize(reader_cfg, DecoderConfig(decoder_type), mem_type, _batch_size, decoder_keep_orig); From 9f75ff13de823ede836405c8814e885a3b9e8220 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 24 Sep 2025 00:10:40 -0500 Subject: [PATCH 009/118] Introduce PipelineSerializer Add support to serialize the args and pipeline details Add support to serialize the tensors. --- rocAL/CMakeLists.txt | 3 +- rocAL/include/pipeline/master_graph.h | 6 +- rocAL/include/pipeline/pipeline_operator.h | 4 +- rocAL/include/pipeline/pipeline_serializer.h | 73 +++++++++ rocAL/proto/rocal.proto | 109 +++++++++++++ rocAL/source/pipeline/master_graph.cpp | 8 + rocAL/source/pipeline/pipeline_operator.cpp | 150 ++++++++++++++++++ rocAL/source/pipeline/pipeline_serializer.cpp | 65 ++++++++ 8 files changed, 415 insertions(+), 3 deletions(-) create mode 100644 rocAL/include/pipeline/pipeline_serializer.h create mode 100644 rocAL/proto/rocal.proto create mode 100644 rocAL/source/pipeline/pipeline_operator.cpp create mode 100644 rocAL/source/pipeline/pipeline_serializer.cpp diff --git a/rocAL/CMakeLists.txt b/rocAL/CMakeLists.txt index c0acfc19f..556c35433 100644 --- a/rocAL/CMakeLists.txt +++ b/rocAL/CMakeLists.txt @@ -256,11 +256,12 @@ if(${BUILD_ROCAL}) protobuf_generate_cpp(TF_PROTO_SRCS TF_PROTO_HEADERS proto/example.proto proto/feature.proto) protobuf_generate_cpp(CAFFE2_PROTO_SRCS CAFFE2_PROTO_HEADERS proto/caffe2_protos.proto) protobuf_generate_cpp(CAFFE_PROTO_SRCS CAFFE_PROTO_HEADERS proto/caffe_protos.proto) + protobuf_generate_cpp(ROCAL_PROTO_SRCS ROCAL_PROTO_HEADERS proto/rocal.proto) link_directories(${AMDRPP_LIBRARIES_DIRS} ${TurboJpeg_LIBRARIES_DIRS} ${PROTOBUF_LIBRARY_DIRS} /usr/local/lib/) file(GLOB_RECURSE SOURCES "source/*.cpp") add_library(${PROJECT_NAME} SHARED ${SOURCES} ${TF_PROTO_SRCS} ${TF_PROTO_HEADERS} ${CAFFE_PROTO_HEADERS} - ${CAFFE_PROTO_SRCS} ${CAFFE2_PROTO_SRCS} ${CAFFE2_PROTO_HEADERS} ${rocdecode_SRCS}) + ${CAFFE_PROTO_SRCS} ${CAFFE2_PROTO_SRCS} ${CAFFE2_PROTO_HEADERS} ${rocdecode_SRCS} ${ROCAL_PROTO_SRCS} ${ROCAL_PROTO_HEADERS}) if("${BACKEND}" STREQUAL "HIP" AND HIP_FOUND) add_dependencies(${PROJECT_NAME} rocAL_hip) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 06086e3b2..5eba1e975 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -52,7 +52,7 @@ THE SOFTWARE. #endif #include "meta_data/randombboxcrop_meta_data_reader.h" #include "rocal_api_types.h" -#include "pipeline/pipeline_operator.h" +#include "pipeline/pipeline_serializer.h" #define MAX_STRING_LENGTH 100 #define MAX_OBJECTS 50 // Setting an arbitrary value 50.(Max number of objects/image in COCO dataset is 93) @@ -153,6 +153,8 @@ class MasterGraph { RocalTensorlayout layout, bool eos); void set_external_source_reader_flag() { _external_source_reader = true; } size_t bounding_box_batch_count(pMetaDataBatch meta_data_batch); + void serialize(size_t &serialized_string_size); + std::string get_serialized_string() { return _serialized_pipeline; } #if ENABLE_OPENCL cl_command_queue get_ocl_cmd_q() { return _device.resources()->cmd_queue; } #endif @@ -244,6 +246,8 @@ class MasterGraph { TimingDbg _rb_block_if_empty_time, _rb_block_if_full_time; std::vector> _pipeline_operators; int _op_idx = 0; + PipelineSerializer _pipeline_serializer; + std::string _serialized_pipeline; // Stores the serialized string of the pipeline }; template diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index b5b148e95..66b26d5fc 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -24,6 +24,7 @@ THE SOFTWARE. #include #include "pipeline/node.h" +#include "rocal.pb.h" // Stores the information for the operator in the pipeline class PipelineOperator { @@ -37,7 +38,8 @@ class PipelineOperator { void set_arguments(std::vector op_arguments) { arguments = op_arguments; } - + void serialize_pipeop_args_to_protobuf(rocal_proto::OperatorDef *opdef); + void serialize_pipeop_inputs_and_outputs_to_protobuf(rocal_proto::OperatorDef *opdef); std::string operator_name; // Name of the Node/operator std::string module_name; // Denotes the type of operator i.e loader/reader/augmentation std::vector arguments; diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h new file mode 100644 index 000000000..382f0f44c --- /dev/null +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -0,0 +1,73 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once + +#include +#include "pipeline/pipeline_operator.h" + +class PipelineSerializer { +public: + PipelineSerializer() {} + ~PipelineSerializer() {} + + // Serialization methods + /** + * @brief Serialize a rocAL pipeline to a file + * @param context The rocAL context containing the pipeline + * @param file_path Path to save the serialized pipeline + * @return RocalStatus indicating success or failure + */ + void serialize_to_file(const std::string& file_path); + + /** + * @brief Serialize a rocAL pipeline to a string + * @param context The rocAL context containing the pipeline + * @param serialized_string Output string containing the serialized pipeline + * @return RocalStatus indicating success or failure + */ + void serialize_to_string(std::string& serialized_string); + + void serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth); + void serialize_output_tensors(TensorList& output_tensors_list); + void serialize_operators(std::vector>& operators); + + /** + * @brief Deserialize a rocAL pipeline from a file + * @param file_path Path to the serialized pipeline file + * @param context Output context containing the deserialized pipeline + * @return RocalStatus indicating success or failure + */ + // RocalStatus deserialize_from_file(const std::string& file_path, Context** context); + + /** + * @brief Deserialize a rocAL pipeline from a string + * @param serialized_string String containing the serialized pipeline + * @param context Output context containing the deserialized pipeline + * @return RocalStatus indicating success or failure + */ + // RocalStatus deserialize_from_string(const std::string& serialized_string, Context** context); + +protected: + rocal_proto::PipelineDef _pipeline; + +}; diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto new file mode 100644 index 000000000..319dd6d51 --- /dev/null +++ b/rocAL/proto/rocal.proto @@ -0,0 +1,109 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +syntax = "proto3"; + +package rocal_proto; + +// Stores the Input/Ouptut tensors +message InputOutput { + string name = 1; + optional string type = 2; + bool is_argument_input = 3; + int32 device = 4; + optional int32 dtype = 5; + optional int32 layout = 6; + optional int32 color_format = 7; + repeated uint64 dims = 8; + uint32 num_dims = 9; +} + +message Parameter { + int32 param_type = 1; + repeated float param_val_float = 2; + repeated int32 param_val_int = 3; + repeated double frequency = 4; // Used only for CustomRand param + optional uint32 size = 5; // Used only for CustomRand param +} + +message EnumType { + string name = 1; + int32 value = 2; +} + +// Vector containers for Arguments (use these when passing vectors) +message FloatVector { + repeated float values = 1; +} + +message IntVector { + repeated int64 values = 1; +} + +message StringVector { + repeated string values = 1; +} + +// Stores a single argument +message Arguments { + string name = 1; + optional string type = 2; + optional string instance_name = 3; + repeated float floats = 4; + repeated int64 ints = 5; + repeated string strings = 6; + repeated bool bools = 7; + repeated uint64 uints = 8; + optional Parameter param = 9; + optional EnumType enum_value = 10; + + // vector storage (deprecated): use *_vectors below instead + bool is_vector = 11 [deprecated = true]; + + // Vector payloads (use these when the argument carries vectors) + repeated FloatVector float_vectors = 12; + repeated IntVector int_vectors = 13; + repeated StringVector string_vectors = 14; +} + +// Stores info about each operator in pipeline +message OperatorDef { + string name = 1; + optional string module_name = 2; + // Arguments + repeated Arguments args = 3; + // Inputs + repeated InputOutput inputs = 4; + repeated InputOutput outputs = 5; +} + +// Stores pipeline arguments and a list of nodes/operators +message PipelineDef { + optional int64 num_threads = 1; + int32 batch_size = 2; + optional int32 device_id = 3; + optional int64 seed = 4; + optional bool rocal_cpu = 5; + optional int32 prefetch_queue_depth = 6; + repeated OperatorDef operators = 7; + repeated InputOutput pipe_outputs = 8; +} diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 8eb902904..d1535f695 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1883,3 +1883,11 @@ void MasterGraph::feed_external_input(const std::vector& input_imag } } } + +void MasterGraph::serialize(size_t &serialized_string_size) { + _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth); + _pipeline_serializer.serialize_operators(_pipeline_operators); + _pipeline_serializer.serialize_output_tensors(_internal_tensor_list); + _pipeline_serializer.serialize_to_string(_serialized_pipeline); + serialized_string_size = _serialized_pipeline.size(); +} diff --git a/rocAL/source/pipeline/pipeline_operator.cpp b/rocAL/source/pipeline/pipeline_operator.cpp new file mode 100644 index 000000000..fc5b64e39 --- /dev/null +++ b/rocAL/source/pipeline/pipeline_operator.cpp @@ -0,0 +1,150 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "pipeline/pipeline_operator.h" + +void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input = false) { + in_out_proto->set_name(tensor->tensor_name()); + in_out_proto->set_device(static_cast(tensor->info().mem_type())); + in_out_proto->set_dtype(static_cast(tensor->info().data_type())); + in_out_proto->set_layout(static_cast(tensor->info().layout())); + in_out_proto->set_color_format(static_cast(tensor->info().color_format())); + for (auto &dim : tensor->info().dims()) + in_out_proto->add_dims(dim); + in_out_proto->set_num_dims(tensor->info().num_of_dims()); + in_out_proto->set_is_argument_input(is_input); +} + +void PipelineOperator::serialize_pipeop_inputs_and_outputs_to_protobuf(rocal_proto::OperatorDef *opdef) { + if (this->module_name == "reader") + return; // Readers do not have tensor outputs, hence return + + // Serialize input tensors to protobuffers + for (auto &node_input : this->node->input()) { + rocal_proto::InputOutput *input = opdef->add_inputs(); + set_tensor_proto(input, node_input, true); + } + + // Serialize output tensors to protobuffers + for (auto &node_output : this->node->output()) { + rocal_proto::InputOutput *output = opdef->add_outputs(); + set_tensor_proto(output, node_output); + } +} + +void PipelineOperator::serialize_pipeop_args_to_protobuf(rocal_proto::OperatorDef *opdef) { + std::vector arguments_list; + + if (this->module_name == "reader") { + arguments_list = this->arguments; + } else { + arguments_list = this->node->get_args_list(); + } + // Iterate through each argument to store in the protobuffers + for (auto &op_arg : arguments_list) { + rocal_proto::Arguments *arg = opdef->add_args(); + arg->set_name(op_arg.arg_name); + arg->set_type(op_arg.type_name); + arg->set_is_vector(op_arg.is_vector); + + if (op_arg.type_name == "nullptr") continue; + if (op_arg.enum_type_name != "") + arg->set_instance_name(op_arg.enum_type_name); + + if (op_arg.is_parameter) { + // TODO - Will be enabled later + // rocal_proto::Parameter *param = arg->mutable_param(); + // serialize_parameter_to_protobuf(param, op_arg); + } else if (op_arg.type_name == "enum") { + rocal_proto::EnumType* enum_arg = arg->mutable_enum_value(); + enum_arg->set_name(op_arg.enum_type_name); + enum_arg->set_value(std::any_cast(op_arg.values[0])); + } else { + // Scalars go to the flat repeated fields; vectors go to repeated *Vector messages + if (op_arg.is_vector) { + if (op_arg.values.empty()) { + // Represent empty vector by adding an empty vector message of the right type + if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr" + || op_arg.type_name == "unsigned" || op_arg.type_name == "size_t") { + static_cast(arg->add_int_vectors()); + } else if (op_arg.type_name == "float") { + static_cast(arg->add_float_vectors()); + } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string" + || op_arg.type_name == "map_string") { + static_cast(arg->add_string_vectors()); + } else { + THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); + } + } else { + if (op_arg.type_name == "int" || op_arg.type_name == "unsigned" || op_arg.type_name == "size_t") { + auto *vec = arg->add_int_vectors(); + for (auto &v : op_arg.values) { + // Map unsigned/size_t to int64 for IntVector as per spec (only Int/Float/String vectors permitted) + if (op_arg.type_name == "unsigned") { + vec->add_values(static_cast(std::any_cast(v))); + } else if (op_arg.type_name == "size_t") { + vec->add_values(static_cast(std::any_cast(v))); + } else { + vec->add_values(static_cast(std::any_cast(v))); + } + } + } else if (op_arg.type_name == "float") { + auto *vec = arg->add_float_vectors(); + for (auto &v : op_arg.values) { + vec->add_values(std::any_cast(v)); + } + } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string" + || op_arg.type_name == "map_string") { + auto *vec = arg->add_string_vectors(); + for (auto &v : op_arg.values) { + vec->add_values(std::any_cast(v)); + } + } else { + THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); + } + } + } else { + // Scalar path (use flat repeated fields) + if (op_arg.values.size() > 1) { + ERR("Argument has more than one value, is_vector should be set to true") + } + for (auto &v : op_arg.values) { + if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr") { + arg->add_ints(std::any_cast(v)); + } else if (op_arg.type_name == "float") { + arg->add_floats(std::any_cast(v)); + } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string") { + arg->add_strings(std::any_cast(v)); + } else if (op_arg.type_name == "bool") { + arg->add_bools(std::any_cast(v)); + } else if (op_arg.type_name == "unsigned") { + arg->add_uints(std::any_cast(v)); + } else if (op_arg.type_name == "size_t") { + arg->add_uints(std::any_cast(v)); + } else { + THROW("Invalid type specified for the Argument " + op_arg.arg_name); + } + } + } + } + } +} diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp new file mode 100644 index 000000000..bb4412fe4 --- /dev/null +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -0,0 +1,65 @@ +/* +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "pipeline/pipeline_serializer.h" + +void PipelineSerializer::serialize_to_string(std::string& serialized_string) { + serialized_string = _pipeline.SerializeAsString(); +} + +void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth) { + _pipeline.set_num_threads(num_threads); + _pipeline.set_batch_size(batch_size); + _pipeline.set_device_id(device_id); + _pipeline.set_rocal_cpu(device_type == RocalMemType::HOST ? true : false); + _pipeline.set_prefetch_queue_depth(prefetch_queue_depth); +} + +void PipelineSerializer::serialize_operators(std::vector>& operators) { + // Serialize all operators + for (auto &pipe_op : operators) { + rocal_proto::OperatorDef *op = _pipeline.add_operators(); + op->set_name(pipe_op->operator_name); + op->set_module_name(pipe_op->module_name); + // Add support to add each argument in the operator + pipe_op->serialize_pipeop_args_to_protobuf(op); + pipe_op->serialize_pipeop_inputs_and_outputs_to_protobuf(op); + } +} + +void PipelineSerializer::serialize_output_tensors(TensorList& output_tensors_list) { + + // Serialize the pipeline outputs + for (size_t idx = 0; idx < output_tensors_list.size(); idx++) { + rocal_proto::InputOutput *output = _pipeline.add_pipe_outputs(); + auto pipe_output = output_tensors_list[idx]; + output->set_name(pipe_output->tensor_name()); + output->set_device(static_cast(pipe_output->info().mem_type())); + output->set_dtype(static_cast(pipe_output->info().data_type())); + output->set_layout(static_cast(pipe_output->info().layout())); + output->set_color_format(static_cast(pipe_output->info().color_format())); + for (auto& dim : pipe_output->info().dims()) + output->add_dims(dim); + output->set_num_dims(pipe_output->info().num_of_dims()); + output->set_is_argument_input(false); + } +} From 8d07c811dc15580e0d048449e01b9bdd4e052d3a Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 24 Sep 2025 00:14:05 -0500 Subject: [PATCH 010/118] Introduce external rocalSerialize API --- rocAL/include/api/rocal_api.h | 4 ++++ rocAL/source/api/rocal_api.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/rocAL/include/api/rocal_api.h b/rocAL/include/api/rocal_api.h index eaf1c54d4..12530d4aa 100644 --- a/rocAL/include/api/rocal_api.h +++ b/rocAL/include/api/rocal_api.h @@ -109,4 +109,8 @@ extern "C" RocalStatus ROCAL_API_CALL rocalRun(RocalContext context); */ extern "C" RocalStatus ROCAL_API_CALL rocalRelease(RocalContext rocal_context); +extern "C" RocalStatus ROCAL_API_CALL rocalSerialize(RocalContext rocal_context, size_t &serialized_string_size); + +extern "C" RocalStatus ROCAL_API_CALL rocalGetSerializedString(RocalContext rocal_context, const char* serialized_string); + #endif diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index 6604c4589..0ab793bfa 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -105,3 +105,37 @@ rocalVerify(RocalContext p_context) { } return ROCAL_OK; } + +RocalStatus ROCAL_API_CALL +rocalSerialize(RocalContext rocal_context, size_t &serialized_string_size) { + auto context = static_cast(rocal_context); + try { + context->master_graph->serialize(serialized_string_size); + } catch (const std::exception& e) { + context->capture_error(e.what()); + ERR(e.what()) + return ROCAL_RUNTIME_ERROR; + } + return ROCAL_OK; +} + +RocalStatus ROCAL_API_CALL +rocalGetSerializedString(RocalContext rocal_context, const char* serialized_string) { + auto context = static_cast(rocal_context); + try { + if (!serialized_string) { + THROW("String copy failed, Invalid pointer passed for serialize") + } + + auto serialize_pipe_string = context->master_graph->get_serialized_string(); + if (serialize_pipe_string.empty()) + THROW("Serialized string is empty, Invoke rocalSerialize before obtaining the string") + std::memcpy(const_cast(serialized_string), serialize_pipe_string.c_str(), serialize_pipe_string.size() + 1); + + } catch (const std::exception& e) { + context->capture_error(e.what()); + ERR(e.what()) + return ROCAL_RUNTIME_ERROR; + } + return ROCAL_OK; +} From 4e8cb1cce8e34ed15dac5faa11305eac386341b0 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 24 Sep 2025 00:15:58 -0500 Subject: [PATCH 011/118] Add support to serialize parameter arguments --- rocAL/include/parameters/parameter_random.h | 6 ++ rocAL/source/pipeline/pipeline_operator.cpp | 92 ++++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/rocAL/include/parameters/parameter_random.h b/rocAL/include/parameters/parameter_random.h index ec49ea05b..61d729c25 100644 --- a/rocAL/include/parameters/parameter_random.h +++ b/rocAL/include/parameters/parameter_random.h @@ -104,6 +104,9 @@ class UniformRand : public Parameter { bool single_value() const override { return (_start == _end); } + std::pair get_start_and_end() { + return std::make_pair(_start, _end); + } private: T _start; @@ -225,6 +228,9 @@ struct CustomRand : public Parameter { bool single_value() const override { return (_values.size() == 1); } + std::vector& get_values() { return _values; } + std::vector& get_frequencies() { return _frequencies; } + unsigned size() { return _size; } private: std::vector _values; //!< Values diff --git a/rocAL/source/pipeline/pipeline_operator.cpp b/rocAL/source/pipeline/pipeline_operator.cpp index fc5b64e39..4b7512e15 100644 --- a/rocAL/source/pipeline/pipeline_operator.cpp +++ b/rocAL/source/pipeline/pipeline_operator.cpp @@ -51,6 +51,93 @@ void PipelineOperator::serialize_pipeop_inputs_and_outputs_to_protobuf(rocal_pro } } +// Template helper function to add parameter values based on type +template +void add_param_value(rocal_proto::Parameter *parameter, const T& value) { + if constexpr (std::is_same_v) { + parameter->add_param_val_int(value); + } else if constexpr (std::is_same_v) { + parameter->add_param_val_float(value); + } +} + +// Template function to safely extract and cast parameter core +template +auto extract_param_core(Argument &op_arg) { + if constexpr (std::is_same_v) { + auto param = std::get(op_arg.param); + return param->core; + } else if constexpr (std::is_same_v) { + auto param = std::get(op_arg.param); + return param->core; + } +} + +// Template function to handle SimpleParameter serialization +template +void serialize_simple_parameter(rocal_proto::Parameter *parameter, Argument &op_arg) { + auto param_core = extract_param_core(op_arg); + auto simple_param = dynamic_cast *>(param_core); + if (simple_param) { + add_param_value(parameter, simple_param->get()); + } +} + +// Template function to handle UniformRand serialization +template +void serialize_uniform_rand(rocal_proto::Parameter *parameter, Argument &op_arg) { + auto param_core = extract_param_core(op_arg); + auto uniform_param = dynamic_cast *>(param_core); + if (uniform_param) { + auto uniform_range = uniform_param->get_start_and_end(); + add_param_value(parameter, uniform_range.first); + add_param_value(parameter, uniform_range.second); + } +} + +// Template function to handle CustomRand serialization +template +void serialize_custom_rand(rocal_proto::Parameter *parameter, Argument &op_arg) { + auto param_core = extract_param_core(op_arg); + auto random_param = dynamic_cast *>(param_core); + if (random_param) { + // Add values + auto values_vec = random_param->get_values(); + for (const auto &val : values_vec) { + add_param_value(parameter, val); + } + + // Add frequencies + auto frequency_vec = random_param->get_frequencies(); + for (const auto &val : frequency_vec) { + parameter->add_frequency(val); + } + + parameter->set_size(random_param->size()); + } +} + +// Type dispatcher function to handle different data types +template +void serialize_parameter_by_type(rocal_proto::Parameter *parameter, Argument &op_arg) { + if (op_arg.enum_type_name == "SimpleParameter") { + serialize_simple_parameter(parameter, op_arg); + } else if (op_arg.enum_type_name == "UniformRand") { + serialize_uniform_rand(parameter, op_arg); + } else if (op_arg.enum_type_name == "CustomRand") { + serialize_custom_rand(parameter, op_arg); + } +} + +// Main function with improved structure and error handling +void serialize_parameter_to_protobuf(rocal_proto::Parameter *parameter, Argument &op_arg) { + if (op_arg.type_name == "int") { + serialize_parameter_by_type(parameter, op_arg); + } else if (op_arg.type_name == "float") { + serialize_parameter_by_type(parameter, op_arg); + } +} + void PipelineOperator::serialize_pipeop_args_to_protobuf(rocal_proto::OperatorDef *opdef) { std::vector arguments_list; @@ -71,9 +158,8 @@ void PipelineOperator::serialize_pipeop_args_to_protobuf(rocal_proto::OperatorDe arg->set_instance_name(op_arg.enum_type_name); if (op_arg.is_parameter) { - // TODO - Will be enabled later - // rocal_proto::Parameter *param = arg->mutable_param(); - // serialize_parameter_to_protobuf(param, op_arg); + rocal_proto::Parameter *param = arg->mutable_param(); + serialize_parameter_to_protobuf(param, op_arg); } else if (op_arg.type_name == "enum") { rocal_proto::EnumType* enum_arg = arg->mutable_enum_value(); enum_arg->set_name(op_arg.enum_type_name); From 8a09a069b58080f2c8513dbb053ff37ac1d295ef Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 24 Sep 2025 06:10:34 -0500 Subject: [PATCH 012/118] Introduce serialize tests --- .../cpp_api/serialization_test/CMakeLists.txt | 59 ++++++ tests/cpp_api/serialization_test/README.md | 58 ++++++ .../serialization_test/serialization_test.cpp | 176 ++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 tests/cpp_api/serialization_test/CMakeLists.txt create mode 100644 tests/cpp_api/serialization_test/README.md create mode 100644 tests/cpp_api/serialization_test/serialization_test.cpp diff --git a/tests/cpp_api/serialization_test/CMakeLists.txt b/tests/cpp_api/serialization_test/CMakeLists.txt new file mode 100644 index 000000000..34c50ddef --- /dev/null +++ b/tests/cpp_api/serialization_test/CMakeLists.txt @@ -0,0 +1,59 @@ +################################################################################ +# +# MIT License +# +# Copyright (c) 2018 - 2025 Advanced Micro Devices, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +################################################################################ +cmake_minimum_required(VERSION 3.10) +# ROCM Path +if(DEFINED ENV{ROCM_PATH}) + set(ROCM_PATH $ENV{ROCM_PATH} CACHE PATH "Default ROCm installation path") +elseif(ROCM_PATH) + message("-- INFO:ROCM_PATH Set -- ${ROCM_PATH}") +else() + set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") +endif() +# Set AMD Clang as default compiler +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED On) +set(CMAKE_CXX_EXTENSIONS ON) +if(NOT DEFINED CMAKE_CXX_COMPILER AND EXISTS "${ROCM_PATH}/bin/amdclang++") + set(CMAKE_C_COMPILER ${ROCM_PATH}/bin/amdclang) + set(CMAKE_CXX_COMPILER ${ROCM_PATH}/bin/amdclang++) +elseif(NOT DEFINED CMAKE_CXX_COMPILER AND NOT EXISTS "${ROCM_PATH}/bin/amdclang++") + set(CMAKE_C_COMPILER clang) + set(CMAKE_CXX_COMPILER clang++) +endif() + +project(serialization_test) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) + +find_package(AMDRPP QUIET) + +include_directories(${ROCM_PATH}/include ${ROCM_PATH}/include/rocal ${PROJECT_SOURCE_DIR}/../../../rocAL/include/api) +link_directories(${ROCM_PATH}/lib) +file(GLOB My_Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${My_Source_Files}) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") +target_link_libraries(${PROJECT_NAME} rocal) diff --git a/tests/cpp_api/serialization_test/README.md b/tests/cpp_api/serialization_test/README.md new file mode 100644 index 000000000..66ef86699 --- /dev/null +++ b/tests/cpp_api/serialization_test/README.md @@ -0,0 +1,58 @@ +# rocAL Serialization Test + +This test demonstrates the rocAL pipeline serialization functionality using a simple pipeline with: +- JPEG file source (`rocalJpegFileSource`) +- Label reader (`rocalCreateLabelReader`) +- Brightness augmentation (`rocalBrightness`) + +## Purpose + +The test validates the `rocalSerialize` and `rocalGetSerializedString` APIs by: +1. Creating a rocAL pipeline with the specified components +2. Serializing the pipeline to get the serialized string size +3. Retrieving and printing the serialized pipeline string +4. Running a few iterations to verify the pipeline works correctly + +## Building + +```bash +cd tests/cpp_api/serialization_test +mkdir build && cd build +cmake .. +make +``` + +## Usage + +```bash +./serialization_test [processing_device] +``` + +### Parameters: +- `image_dataset_folder`: Path to folder containing JPEG images (required) +- `processing_device`: 0 for CPU, 1 for GPU (optional, default: 0) + +### Example: +```bash +# Using CPU processing +./serialization_test /path/to/images 0 + +# Using GPU processing +./serialization_test /path/to/images 1 +``` + +## Expected Output + +The test will: +1. Create the rocAL pipeline +2. Display pipeline information (dimensions, augmentation count) +3. Serialize the pipeline and show the serialized string size +4. Print the complete serialized pipeline string +5. Run a few iterations to process images and display image names with labels +6. Report successful completion + +## Test Data + +You can use the sample data provided in the rocAL repository: +```bash +./serialization_test ../../../data/images/AMD-tinyDataSet 0 diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp new file mode 100644 index 000000000..1a9040b2e --- /dev/null +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -0,0 +1,176 @@ +/* +MIT License + +Copyright (c) 2018 - 2025 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include +#include + +#include "rocal_api.h" + +int main(int argc, const char **argv) { + // check command-line usage + const int MIN_ARG_COUNT = 2; + if (argc < MIN_ARG_COUNT) { + std::cout << "Usage: serialization_test \n"; + return -1; + } + + int argIdx = 1; + const char *folderPath = argv[argIdx++]; + bool processing_device = 0; + + if (argc > argIdx) + processing_device = atoi(argv[argIdx++]); + + const int inputBatchSize = 2; + RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB24; + + std::cout << ">>> Running serialization test on " << (processing_device ? "GPU" : "CPU") << std::endl; + + // Create rocAL context + auto handle = rocalCreate(inputBatchSize, + processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, + 0, 1); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Could not create the Rocal context\n"; + return -1; + } + + /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ + + // Create JPEG file source + RocalTensor decoded_output = rocalJpegFileSource(handle, folderPath, color_format, 1, false, false); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + // Create label reader + rocalCreateLabelReader(handle, folderPath); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Label reader could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + // Add brightness augmentation (mark as output) + RocalTensor brightness_output = rocalBrightnessFixed(handle, decoded_output, 0.5, 1.5, true); + + if (rocalGetStatus(handle) != ROCAL_OK) { + std::cout << "Brightness augmentation could not initialize : " << rocalGetErrorMessage(handle) << std::endl; + return -1; + } + + // Verify and build the augmentation graph + if (rocalVerify(handle) != ROCAL_OK) { + std::cout << "Could not verify the augmentation graph" << std::endl; + return -1; + } + + std::cout << "Pipeline created successfully!" << std::endl; + std::cout << "Augmented copies count: " << rocalGetAugmentationBranchCount(handle) << std::endl; + std::cout << "Output dimensions: " << rocalGetOutputWidth(handle) << "x" << rocalGetOutputHeight(handle) << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Serialization Test <<<<<<<<<<<<<<<<<<<*/ + + std::cout << "\n=== Testing Pipeline Serialization ===" << std::endl; + + // Get the size of the serialized string + size_t serialized_string_size = 0; + RocalStatus serialize_status = rocalSerialize(handle, serialized_string_size); + + if (serialize_status != ROCAL_OK) { + std::cout << "Failed to serialize pipeline: " << rocalGetErrorMessage(handle) << std::endl; + rocalRelease(handle); + return -1; + } + + std::cout << "Serialized string size: " << serialized_string_size << " bytes" << std::endl; + + // Allocate buffer for the serialized string + std::vector serialized_buffer(serialized_string_size + 1, '\0'); + + // Get the actual serialized string + RocalStatus get_string_status = rocalGetSerializedString(handle, serialized_buffer.data()); + + if (get_string_status != ROCAL_OK) { + std::cout << "Failed to get serialized string: " << rocalGetErrorMessage(handle) << std::endl; + rocalRelease(handle); + return -1; + } + + std::cout << "\n=== Serialized Pipeline String ===" << std::endl; + std::cout << serialized_buffer.data() << std::endl; + std::cout << "=== End of Serialized String ===" << std::endl; + + /*>>>>>>>>>>>>>>>>>>> Test Pipeline Execution <<<<<<<<<<<<<<<<<<<*/ + + std::cout << "\n=== Testing Pipeline Execution ===" << std::endl; + std::cout << "Available images: " << rocalGetRemainingImages(handle) << std::endl; + + // Run a few iterations to test the pipeline + const int test_iterations = 2; + int ImageNameLen[inputBatchSize]; + std::vector names; + names.resize(inputBatchSize); + + for (int iter = 0; iter < test_iterations && !rocalIsEmpty(handle); iter++) { + std::cout << "\nIteration " << (iter + 1) << ":" << std::endl; + + if (rocalRun(handle) != 0) { + std::cout << "rocalRun Failed with runtime error" << std::endl; + rocalRelease(handle); + return -1; + } + + // Get labels + RocalTensorList labels = rocalGetImageLabels(handle); + + // Get image names + unsigned imagename_size = rocalGetImageNameLen(handle, ImageNameLen); + std::vector imageNames(imagename_size); + rocalGetImageName(handle, imageNames.data()); + std::string imageNamesStr(imageNames.data()); + + int pos = 0; + int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); + for (int i = 0; i < inputBatchSize; i++) { + names[i] = imageNamesStr.substr(pos, ImageNameLen[i]); + pos += ImageNameLen[i]; + std::cout << " Image: " << names[i] << " | Label: " << labels_buffer[i] << std::endl; + } + } + + std::cout << "\n=== Serialization Test Completed Successfully ===" << std::endl; + + // Clean up + rocalRelease(handle); + + return 0; +} From cba503f252dccf89dcf9bc42ddb7aeffa4d3f17b Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Thu, 25 Sep 2025 14:49:04 +0530 Subject: [PATCH 013/118] Remove redundant static cast Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../source/augmentations/geometry_augmentations/node_resize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp b/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp index 10d16307f..4000b785f 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp @@ -86,7 +86,7 @@ void ResizeNode::update_node() { void ResizeNode::init(unsigned dest_width, unsigned dest_height, ResizeScalingMode scaling_mode, const std::vector &max_size, ResizeInterpolationType interpolation_type) { _interpolation_type = (int)interpolation_type; - _scaling_mode = static_cast(scaling_mode); + _scaling_mode = scaling_mode; _out_width = dest_width; _out_height = dest_height; if (max_size.size() > 0) { From 77676a4ea90846dd270adfa89f50331a713bf475 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 25 Sep 2025 09:52:57 -0500 Subject: [PATCH 014/118] Add support to dump images using OpenCV --- .../cpp_api/serialization_test/CMakeLists.txt | 59 ++++++++++++++++++- .../serialization_test/serialization_test.cpp | 55 ++++++++++++++++- 2 files changed, 110 insertions(+), 4 deletions(-) diff --git a/tests/cpp_api/serialization_test/CMakeLists.txt b/tests/cpp_api/serialization_test/CMakeLists.txt index 34c50ddef..0098dfd24 100644 --- a/tests/cpp_api/serialization_test/CMakeLists.txt +++ b/tests/cpp_api/serialization_test/CMakeLists.txt @@ -46,8 +46,35 @@ endif() project(serialization_test) -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake) +find_library(ROCAL_LIBRARY NAMES rocal HINTS ${ROCM_PATH}/lib) +find_path(ROCAL_INCLUDE_DIR NAMES rocal_api.h PATHS ${ROCM_PATH}/include/rocal) +if(ROCAL_LIBRARY AND ROCAL_INCLUDE_DIR) + set(ROCAL_FOUND TRUE) + message("-- ${White}${PROJECT_NAME}: Using rocAL -- \n\tLibraries:${ROCAL_LIBRARY} \n\tIncludes:${ROCAL_INCLUDE_DIR}${ColourReset}") +endif() + +if(NOT ROCAL_FOUND) + message("-- ${Yellow}${PROJECT_NAME} requires rocAL. Install rocAL before running CTests") +else() + set(RPP_BACKEND_HIP_FOUND 0) + if(EXISTS ${ROCM_PATH}/include/rpp/rpp_backend.h) + file(READ ${ROCM_PATH}/include/rpp/rpp_backend.h RPP_BACKEND_FILE) + string(REGEX MATCH "RPP_BACKEND_HIP ([0-9]*)" _ ${RPP_BACKEND_FILE}) + set(RPP_BACKEND_HIP_FOUND ${CMAKE_MATCH_1}) + endif() + if(NOT DEFINED BACKEND AND RPP_BACKEND_HIP_FOUND) + set(BACKEND "HIP") + elseif(NOT DEFINED BACKEND) + set(BACKEND "CPU") + endif() +endif(NOT ROCAL_FOUND) +message("-- ${BoldBlue}Backend set to -- ${BACKEND}${ColourReset}") + +list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/lib/cmake) +list(APPEND CMAKE_MODULE_PATH ${ROCM_PATH}/share/rocal/test/cmake) + +find_package(OpenCV QUIET) find_package(AMDRPP QUIET) include_directories(${ROCM_PATH}/include ${ROCM_PATH}/include/rocal ${PROJECT_SOURCE_DIR}/../../../rocAL/include/api) @@ -55,5 +82,35 @@ link_directories(${ROCM_PATH}/lib) file(GLOB My_Source_Files ./*.cpp) add_executable(${PROJECT_NAME} ${My_Source_Files}) +if("${BACKEND}" STREQUAL "HIP") + find_package(HIP QUIET) + if(HIP_FOUND) + message("-- ${White}${PROJECT_NAME} -- Using HIP - Path:" ${HIP_PATH} "\tVersion:" ${HIP_VERSION} "\tCompiler:" ${HIP_COMPILER}${ColourReset}) + include_directories(${HIP_INCLUDE_DIRS} ${HIP_INCLUDE_DIRS}/hip) + target_link_libraries(${PROJECT_NAME} ${HIP_LIBRARIES}) + target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_HIP=1) + else() + set(BACKEND "CPU") + message("-- ${Yellow}HIP not found! ${PROJECT_NAME} set to build with CPU backend${ColourReset}") + endif() +endif() + +if(OpenCV_FOUND) + if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) + else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) + endif() + else() + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + endif() +else() + message(FATAL_ERROR "OpenCV Not Found -- No Display Support") +endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") target_link_libraries(${PROJECT_NAME} rocal) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 1a9040b2e..116eadf94 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -31,6 +31,16 @@ THE SOFTWARE. #include "rocal_api.h" +#ifdef USE_OPENCV_4 +#include +#include +#include +#else +#include +#include +#include +#endif + int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; @@ -114,10 +124,10 @@ int main(int argc, const char **argv) { std::cout << "Serialized string size: " << serialized_string_size << " bytes" << std::endl; // Allocate buffer for the serialized string - std::vector serialized_buffer(serialized_string_size + 1, '\0'); + std::string serialized_pipe_string(serialized_string_size, '\0'); // Get the actual serialized string - RocalStatus get_string_status = rocalGetSerializedString(handle, serialized_buffer.data()); + RocalStatus get_string_status = rocalGetSerializedString(handle, serialized_pipe_string.c_str()); if (get_string_status != ROCAL_OK) { std::cout << "Failed to get serialized string: " << rocalGetErrorMessage(handle) << std::endl; @@ -126,7 +136,7 @@ int main(int argc, const char **argv) { } std::cout << "\n=== Serialized Pipeline String ===" << std::endl; - std::cout << serialized_buffer.data() << std::endl; + std::cout << serialized_pipe_string << std::endl; std::cout << "=== End of Serialized String ===" << std::endl; /*>>>>>>>>>>>>>>>>>>> Test Pipeline Execution <<<<<<<<<<<<<<<<<<<*/ @@ -140,6 +150,21 @@ int main(int argc, const char **argv) { std::vector names; names.resize(inputBatchSize); + /*>>>>>>>>>>>>>>>>>>> Display using OpenCV <<<<<<<<<<<<<<<<<*/ + int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * inputBatchSize; + int w = rocalGetOutputWidth(handle); + int p = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? 3 : 1); + auto cv_color_format = ((color_format == RocalImageColor::ROCAL_COLOR_RGB24) ? CV_8UC3 : CV_8UC1); + cv::Mat mat_output(h, w, cv_color_format); + cv::Mat mat_input(h, w, cv_color_format); + cv::Mat mat_color; + + // Variables for OpenCV display + int col_counter = 0; + int number_of_cols = 1; + bool display_all = true; + const char* outName = "serialization_test_output"; + for (int iter = 0; iter < test_iterations && !rocalIsEmpty(handle); iter++) { std::cout << "\nIteration " << (iter + 1) << ":" << std::endl; @@ -165,6 +190,30 @@ int main(int argc, const char **argv) { pos += ImageNameLen[i]; std::cout << " Image: " << names[i] << " | Label: " << labels_buffer[i] << std::endl; } + + // Copy Image data from handle + rocalCopyToOutput(handle, mat_input.data, h * w * p); + + std::vector compression_params; + compression_params.push_back(cv::IMWRITE_PNG_COMPRESSION); + compression_params.push_back(9); + + mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); + std::string out_filename = std::string(outName) + ".png"; // in case the user specifies non png filename + if (display_all) + out_filename = std::string(outName) + std::to_string(iter) + ".png"; // in case the user specifies non png filename + + if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { +#ifdef USE_OPENCV_4 + cv::cvtColor(mat_output, mat_color, cv::COLOR_RGB2BGR); +#else + cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); +#endif + cv::imwrite(out_filename, mat_color, compression_params); + } else { + cv::imwrite(out_filename, mat_output, compression_params); + } + col_counter = (col_counter + 1) % number_of_cols; } std::cout << "\n=== Serialization Test Completed Successfully ===" << std::endl; From fb09c21b93e9419089165d8d6017d49e6ce41585 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 25 Sep 2025 10:03:48 -0500 Subject: [PATCH 015/118] Update CMakeLists --- .../cpp_api/serialization_test/CMakeLists.txt | 88 +++++-------------- 1 file changed, 23 insertions(+), 65 deletions(-) diff --git a/tests/cpp_api/serialization_test/CMakeLists.txt b/tests/cpp_api/serialization_test/CMakeLists.txt index 0098dfd24..62746af63 100644 --- a/tests/cpp_api/serialization_test/CMakeLists.txt +++ b/tests/cpp_api/serialization_test/CMakeLists.txt @@ -24,6 +24,7 @@ # ################################################################################ cmake_minimum_required(VERSION 3.10) + # ROCM Path if(DEFINED ENV{ROCM_PATH}) set(ROCM_PATH $ENV{ROCM_PATH} CACHE PATH "Default ROCm installation path") @@ -32,85 +33,42 @@ elseif(ROCM_PATH) else() set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path") endif() -# Set AMD Clang as default compiler + +# Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED On) -set(CMAKE_CXX_EXTENSIONS ON) -if(NOT DEFINED CMAKE_CXX_COMPILER AND EXISTS "${ROCM_PATH}/bin/amdclang++") - set(CMAKE_C_COMPILER ${ROCM_PATH}/bin/amdclang) - set(CMAKE_CXX_COMPILER ${ROCM_PATH}/bin/amdclang++) -elseif(NOT DEFINED CMAKE_CXX_COMPILER AND NOT EXISTS "${ROCM_PATH}/bin/amdclang++") - set(CMAKE_C_COMPILER clang) - set(CMAKE_CXX_COMPILER clang++) -endif() project(serialization_test) -find_library(ROCAL_LIBRARY NAMES rocal HINTS ${ROCM_PATH}/lib) -find_path(ROCAL_INCLUDE_DIR NAMES rocal_api.h PATHS ${ROCM_PATH}/include/rocal) - -if(ROCAL_LIBRARY AND ROCAL_INCLUDE_DIR) - set(ROCAL_FOUND TRUE) - message("-- ${White}${PROJECT_NAME}: Using rocAL -- \n\tLibraries:${ROCAL_LIBRARY} \n\tIncludes:${ROCAL_INCLUDE_DIR}${ColourReset}") -endif() - -if(NOT ROCAL_FOUND) - message("-- ${Yellow}${PROJECT_NAME} requires rocAL. Install rocAL before running CTests") -else() - set(RPP_BACKEND_HIP_FOUND 0) - if(EXISTS ${ROCM_PATH}/include/rpp/rpp_backend.h) - file(READ ${ROCM_PATH}/include/rpp/rpp_backend.h RPP_BACKEND_FILE) - string(REGEX MATCH "RPP_BACKEND_HIP ([0-9]*)" _ ${RPP_BACKEND_FILE}) - set(RPP_BACKEND_HIP_FOUND ${CMAKE_MATCH_1}) - endif() - if(NOT DEFINED BACKEND AND RPP_BACKEND_HIP_FOUND) - set(BACKEND "HIP") - elseif(NOT DEFINED BACKEND) - set(BACKEND "CPU") - endif() -endif(NOT ROCAL_FOUND) -message("-- ${BoldBlue}Backend set to -- ${BACKEND}${ColourReset}") - -list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/lib/cmake) -list(APPEND CMAKE_MODULE_PATH ${ROCM_PATH}/share/rocal/test/cmake) +# Find required packages +find_package(OpenCV REQUIRED) -find_package(OpenCV QUIET) -find_package(AMDRPP QUIET) +# Include directories +include_directories(${ROCM_PATH}/include ${ROCM_PATH}/include/rocal) -include_directories(${ROCM_PATH}/include ${ROCM_PATH}/include/rocal ${PROJECT_SOURCE_DIR}/../../../rocAL/include/api) +# Link directories link_directories(${ROCM_PATH}/lib) + +# Source files file(GLOB My_Source_Files ./*.cpp) add_executable(${PROJECT_NAME} ${My_Source_Files}) -if("${BACKEND}" STREQUAL "HIP") - find_package(HIP QUIET) - if(HIP_FOUND) - message("-- ${White}${PROJECT_NAME} -- Using HIP - Path:" ${HIP_PATH} "\tVersion:" ${HIP_VERSION} "\tCompiler:" ${HIP_COMPILER}${ColourReset}) - include_directories(${HIP_INCLUDE_DIRS} ${HIP_INCLUDE_DIRS}/hip) - target_link_libraries(${PROJECT_NAME} ${HIP_LIBRARIES}) - target_compile_definitions(${PROJECT_NAME} PUBLIC ENABLE_HIP=1) - else() - set(BACKEND "CPU") - message("-- ${Yellow}HIP not found! ${PROJECT_NAME} set to build with CPU backend${ColourReset}") - endif() -endif() - -if(OpenCV_FOUND) - if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) - message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") - include_directories(${OpenCV_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() +# OpenCV configuration +if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) + message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") + include_directories(${OpenCV_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) + if(${OpenCV_VERSION_MAJOR} EQUAL 4) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) endif() else() - message(FATAL_ERROR "OpenCV Not Found -- No Display Support") + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mf16c -Wall ") +# Compiler flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall") + +# Link libraries target_link_libraries(${PROJECT_NAME} rocal) From 72ca736ee06e88f57bab5cb93d9be21538afa06e Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 25 Sep 2025 10:04:58 -0500 Subject: [PATCH 016/118] Update copyright --- tests/cpp_api/serialization_test/CMakeLists.txt | 2 +- tests/cpp_api/serialization_test/serialization_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cpp_api/serialization_test/CMakeLists.txt b/tests/cpp_api/serialization_test/CMakeLists.txt index 62746af63..76c145694 100644 --- a/tests/cpp_api/serialization_test/CMakeLists.txt +++ b/tests/cpp_api/serialization_test/CMakeLists.txt @@ -2,7 +2,7 @@ # # MIT License # -# Copyright (c) 2018 - 2025 Advanced Micro Devices, Inc. +# Copyright (c) 2025 Advanced Micro Devices, Inc. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 116eadf94..b2a3ca968 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2018 - 2025 Advanced Micro Devices, Inc. All rights reserved. +Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 604ce6aca04d8b018896ccdc4f880968cfcef145 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 25 Sep 2025 10:16:21 -0500 Subject: [PATCH 017/118] Remove semicolon for enum macro --- rocAL/include/pipeline/commons.h | 12 ++++++------ rocAL/include/readers/image/image_reader.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rocAL/include/pipeline/commons.h b/rocAL/include/pipeline/commons.h index b3750d03a..0f4e7a3a0 100644 --- a/rocAL/include/pipeline/commons.h +++ b/rocAL/include/pipeline/commons.h @@ -225,7 +225,7 @@ enum MissingComponentsBehaviour { MISSING_COMPONENT_SKIP, MISSING_COMPONENT_EMPTY }; -AUTO_REGISTER_ENUM(MissingComponentsBehaviour); +AUTO_REGISTER_ENUM(MissingComponentsBehaviour) /*! \brief Internal Resize Scaling Mode enum * Internal version of RocalResizeScalingMode for use within rocAL implementation @@ -237,7 +237,7 @@ enum class ResizeScalingMode { NOT_LARGER, MIN_MAX }; -AUTO_REGISTER_ENUM(ResizeScalingMode); +AUTO_REGISTER_ENUM(ResizeScalingMode) /*! \brief Internal Resize Interpolation Type enum * Internal version of RocalResizeInterpolationType for use within rocAL implementation @@ -250,7 +250,7 @@ enum class ResizeInterpolationType { GAUSSIAN, TRIANGULAR }; -AUTO_REGISTER_ENUM(ResizeInterpolationType); +AUTO_REGISTER_ENUM(ResizeInterpolationType) /*! \brief Internal Mel Scale Formula enum * Internal version of RocalMelScaleFormula for use within rocAL implementation @@ -259,7 +259,7 @@ enum class MelScaleFormula { SLANEY = 0, HTK }; -AUTO_REGISTER_ENUM(MelScaleFormula); +AUTO_REGISTER_ENUM(MelScaleFormula) /*! \brief Internal Audio Border Type enum * Internal version of RocalAudioBorderType for use within rocAL implementation @@ -269,7 +269,7 @@ enum class AudioBorderType { CLAMP, REFLECT }; -AUTO_REGISTER_ENUM(AudioBorderType); +AUTO_REGISTER_ENUM(AudioBorderType) /*! \brief Internal Out Of Bounds Policy enum * Internal version of RocalOutOfBoundsPolicy for use within rocAL implementation @@ -279,4 +279,4 @@ enum class OutOfBoundsPolicy { TRIMTOSHAPE, ERROR }; -AUTO_REGISTER_ENUM(OutOfBoundsPolicy); +AUTO_REGISTER_ENUM(OutOfBoundsPolicy) diff --git a/rocAL/include/readers/image/image_reader.h b/rocAL/include/readers/image/image_reader.h index 61071eb00..2e5ca297b 100644 --- a/rocAL/include/readers/image/image_reader.h +++ b/rocAL/include/readers/image/image_reader.h @@ -61,7 +61,7 @@ enum class ExternalSourceFileMode { RAWDATA_UNCOMPRESSED = 2, NONE = 3, }; -AUTO_REGISTER_ENUM(ExternalSourceFileMode); +AUTO_REGISTER_ENUM(ExternalSourceFileMode) struct ShardingInfo { RocalBatchPolicy last_batch_policy; From ef53616d724eadd3e65ce6d3d086b8456dca90c0 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 25 Sep 2025 10:18:33 -0500 Subject: [PATCH 018/118] Modify name of macro --- rocAL/include/decoders/image/decoder.h | 2 +- rocAL/include/meta_data/meta_data_reader.h | 2 +- rocAL/include/pipeline/commons.h | 28 +++++++++++----------- rocAL/include/pipeline/enum_registry.h | 4 ++-- rocAL/include/readers/image/image_reader.h | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/rocAL/include/decoders/image/decoder.h b/rocAL/include/decoders/image/decoder.h index c283d902f..4e324aa48 100644 --- a/rocAL/include/decoders/image/decoder.h +++ b/rocAL/include/decoders/image/decoder.h @@ -45,7 +45,7 @@ enum class DecoderType { ROCJPEG_DEC = 7, //!< rocJpeg hardware decoder for decoding jpeg files ROCJPEG_CROPPED = 8 //!< For partial decoding of jpeg files using rocJpeg hardware decoder }; -AUTO_REGISTER_ENUM(DecoderType) +REGISTER_ENUM(DecoderType) class DecoderConfig { public: diff --git a/rocAL/include/meta_data/meta_data_reader.h b/rocAL/include/meta_data/meta_data_reader.h index 56c2bc00d..5c7c7850a 100644 --- a/rocAL/include/meta_data/meta_data_reader.h +++ b/rocAL/include/meta_data/meta_data_reader.h @@ -45,7 +45,7 @@ enum class MetaDataReaderType { MXNET_META_DATA_READER, WEBDATASET_META_DATA_READER }; -AUTO_REGISTER_ENUM(MetaDataReaderType) +REGISTER_ENUM(MetaDataReaderType) struct MetaDataConfig { private: diff --git a/rocAL/include/pipeline/commons.h b/rocAL/include/pipeline/commons.h index 0f4e7a3a0..c1ba91112 100644 --- a/rocAL/include/pipeline/commons.h +++ b/rocAL/include/pipeline/commons.h @@ -55,7 +55,7 @@ enum class RocalTensorlayout { NCDHW, NONE }; -AUTO_REGISTER_ENUM(RocalTensorlayout) +REGISTER_ENUM(RocalTensorlayout) /*! \brief Tensor data type * @@ -70,13 +70,13 @@ enum class RocalTensorDataType { INT32, INT16 }; -AUTO_REGISTER_ENUM(RocalTensorDataType) +REGISTER_ENUM(RocalTensorDataType) enum class RocalAffinity { GPU = 0, CPU }; -AUTO_REGISTER_ENUM(RocalAffinity) +REGISTER_ENUM(RocalAffinity) /*! \brief Color formats currently supported by Rocal SDK as input/output * @@ -87,7 +87,7 @@ enum class RocalColorFormat { U8, RGB_PLANAR, }; -AUTO_REGISTER_ENUM(RocalColorFormat) +REGISTER_ENUM(RocalColorFormat) /*! \brief Memory type, host or device * @@ -98,7 +98,7 @@ enum class RocalMemType { OCL, HIP }; -AUTO_REGISTER_ENUM(RocalMemType) +REGISTER_ENUM(RocalMemType) /*! \brief Decoder mode for Video decoding * @@ -108,7 +108,7 @@ enum class DecodeMode { ROCDECODE = 0, CPU }; -AUTO_REGISTER_ENUM(DecodeMode) +REGISTER_ENUM(DecodeMode) /*! \brief Tensor ROI type * @@ -118,7 +118,7 @@ enum class RocalROIType { LTRB = 0, XYWH }; -AUTO_REGISTER_ENUM(RocalROIType) +REGISTER_ENUM(RocalROIType) /*! \brief Tensor ROI in LTRB format * @@ -181,7 +181,7 @@ enum RocalBatchPolicy { DROP, PARTIAL }; -AUTO_REGISTER_ENUM(RocalBatchPolicy) +REGISTER_ENUM(RocalBatchPolicy) template class BatchRNG { @@ -225,7 +225,7 @@ enum MissingComponentsBehaviour { MISSING_COMPONENT_SKIP, MISSING_COMPONENT_EMPTY }; -AUTO_REGISTER_ENUM(MissingComponentsBehaviour) +REGISTER_ENUM(MissingComponentsBehaviour) /*! \brief Internal Resize Scaling Mode enum * Internal version of RocalResizeScalingMode for use within rocAL implementation @@ -237,7 +237,7 @@ enum class ResizeScalingMode { NOT_LARGER, MIN_MAX }; -AUTO_REGISTER_ENUM(ResizeScalingMode) +REGISTER_ENUM(ResizeScalingMode) /*! \brief Internal Resize Interpolation Type enum * Internal version of RocalResizeInterpolationType for use within rocAL implementation @@ -250,7 +250,7 @@ enum class ResizeInterpolationType { GAUSSIAN, TRIANGULAR }; -AUTO_REGISTER_ENUM(ResizeInterpolationType) +REGISTER_ENUM(ResizeInterpolationType) /*! \brief Internal Mel Scale Formula enum * Internal version of RocalMelScaleFormula for use within rocAL implementation @@ -259,7 +259,7 @@ enum class MelScaleFormula { SLANEY = 0, HTK }; -AUTO_REGISTER_ENUM(MelScaleFormula) +REGISTER_ENUM(MelScaleFormula) /*! \brief Internal Audio Border Type enum * Internal version of RocalAudioBorderType for use within rocAL implementation @@ -269,7 +269,7 @@ enum class AudioBorderType { CLAMP, REFLECT }; -AUTO_REGISTER_ENUM(AudioBorderType) +REGISTER_ENUM(AudioBorderType) /*! \brief Internal Out Of Bounds Policy enum * Internal version of RocalOutOfBoundsPolicy for use within rocAL implementation @@ -279,4 +279,4 @@ enum class OutOfBoundsPolicy { TRIMTOSHAPE, ERROR }; -AUTO_REGISTER_ENUM(OutOfBoundsPolicy) +REGISTER_ENUM(OutOfBoundsPolicy) diff --git a/rocAL/include/pipeline/enum_registry.h b/rocAL/include/pipeline/enum_registry.h index 2736e5851..f4b5a141d 100644 --- a/rocAL/include/pipeline/enum_registry.h +++ b/rocAL/include/pipeline/enum_registry.h @@ -104,9 +104,9 @@ class EnumRegistry { * \param EnumType The enum type to register * * Uses a static variable with lambda function to ensure proper initialization timing. - * Usage: AUTO_REGISTER_ENUM(MyEnumType) + * Usage: REGISTER_ENUM(MyEnumType) */ -#define AUTO_REGISTER_ENUM(EnumType) \ +#define REGISTER_ENUM(EnumType) \ static bool enum_registered_##EnumType = []() { \ EnumRegistry::getInstance().registerEnum(#EnumType); \ return true; \ diff --git a/rocAL/include/readers/image/image_reader.h b/rocAL/include/readers/image/image_reader.h index 2e5ca297b..99428f544 100644 --- a/rocAL/include/readers/image/image_reader.h +++ b/rocAL/include/readers/image/image_reader.h @@ -53,7 +53,7 @@ enum class StorageType { WEBDATASET_RECORDS = 10, // tar files - webdataset format NUMPY_DATA = 11 // to support reading from numpy files }; -AUTO_REGISTER_ENUM(StorageType) +REGISTER_ENUM(StorageType) enum class ExternalSourceFileMode { FILENAME = 0, @@ -61,7 +61,7 @@ enum class ExternalSourceFileMode { RAWDATA_UNCOMPRESSED = 2, NONE = 3, }; -AUTO_REGISTER_ENUM(ExternalSourceFileMode) +REGISTER_ENUM(ExternalSourceFileMode) struct ShardingInfo { RocalBatchPolicy last_batch_policy; From bb665e583304d27b29cdeae1b7ed56894b2201ac Mon Sep 17 00:00:00 2001 From: Fiona Gladwin <121928245+fgladwin@users.noreply.github.com> Date: Mon, 29 Sep 2025 12:14:51 +0530 Subject: [PATCH 019/118] Change enums to scoped enums in commons.h --- rocAL/include/pipeline/commons.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/commons.h b/rocAL/include/pipeline/commons.h index c1ba91112..1cab15a87 100644 --- a/rocAL/include/pipeline/commons.h +++ b/rocAL/include/pipeline/commons.h @@ -176,7 +176,7 @@ struct Timing { DROP - The last batch is dropped if it cannot be fully filled with data from the current epoch. PARTIAL - The last batch is partially filled with the remaining data from the current epoch, keeping the rest of the samples empty. (currently this policy works similar to FILL in rocAL, PARTIAL policy needs to be handled in the pytorch iterator) */ -enum RocalBatchPolicy { +enum class RocalBatchPolicy { FILL = 0, DROP, PARTIAL @@ -220,7 +220,7 @@ class BatchRNG { /*! \brief MissingComponentsBehaviour for Webdataset * */ -enum MissingComponentsBehaviour { +enum class MissingComponentsBehaviour { MISSING_COMPONENT_ERROR = 0, MISSING_COMPONENT_SKIP, MISSING_COMPONENT_EMPTY From d9d527ed3d0d1234bda0ca511d29baf949c4a789 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Mon, 29 Sep 2025 06:17:56 -0500 Subject: [PATCH 020/118] Code reorganization Create single constructor with check for different data types in Argument class --- rocAL/include/pipeline/argument.h | 275 ++++++++++++++++-------- rocAL/include/pipeline/argument_types.h | 26 ++- 2 files changed, 206 insertions(+), 95 deletions(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index 450507a6d..193c489f1 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -21,40 +21,82 @@ THE SOFTWARE. */ #pragma once -#include + #include +#include +#include +#include +#include #include #include #include -#include #include -#include -#include #include "pipeline/argument_types.h" +#include "pipeline/commons.h" #include "pipeline/enum_registry.h" #include "parameters/parameter_factory.h" -#include "pipeline/commons.h" /** * @brief Argument class stores the details of each argument in the Node * * This class encapsulates argument information for pipeline nodes, supporting - * various data types including basic types, enums, vectors, maps, and parameters. + * various data types including basic types, enums, vectors, maps, and parameters. + * + * The class provides type-safe storage and retrieval of arguments with support for: + * - Basic types (int, float, string, etc.) + * - Enum types with registry lookup + * - Vector containers + * - String-to-string maps + * - Shared pointers + * - Parameter objects (FloatParam, IntParam) */ class Argument { - public: - std::string arg_name; ///< Name of the argument - std::string type_name; ///< Denotes the data type of the argument - std::string enum_type_name; ///< Denotes the name of the enum - bool is_vector = false; ///< True if the argument contains vector data - bool is_parameter = false; ///< True if the argument is a parameter object - bool is_null_ptr = false; ///< True if the argument represents a null pointer - std::vector values; ///< Storage for argument values (can change to std::variant later) - pParam param; ///< Parameter stored for parameter-type arguments - - private: - // Helper method to get type name from registry or built-in types +public: + // Public member variables + std::string arg_name; ///< Name of the argument + std::string type_name; ///< Denotes the data type of the argument + std::string enum_type_name; ///< Denotes the name of the enum + bool is_vector = false; ///< True if the argument contains vector data + bool is_parameter = false; ///< True if the argument is a parameter object + bool is_null_ptr = false; ///< True if the argument represents a null pointer + std::vector values; ///< Storage for argument values (can change to std::variant later) + pParam param; ///< Parameter stored for parameter-type arguments + + // Constructors + + /** + * @brief Unified template constructor for all data types + * @tparam T The type of the value being stored + * @param name The name of the argument + * @param val The value to store + * @throws std::runtime_error if the type is unknown or unsupported + */ + template + explicit Argument(std::string name, T&& val) : arg_name(std::move(name)) { + + if constexpr (std::is_enum_v>) { + constructFromEnum(std::forward(val)); + } else if constexpr (is_vector_type_v>) { + constructFromVector(std::forward(val)); + } else if constexpr (is_shared_ptr_v>) { + constructFromSharedPtr(std::forward(val)); + } else if constexpr (is_string_map_v>) { + constructFromMap(std::forward(val)); + } else if constexpr (is_param_type_v>) { + constructFromParam(std::forward(val)); + } else { + constructFromBasicType(std::forward(val)); + } + } + + +private: + /** + * @brief Helper method to get type name from registry or built-in types + * @tparam T The type to get the name for + * @return The string representation of the type name + */ template std::string getTypeName() const { using DecayedType = std::decay_t; @@ -69,109 +111,156 @@ class Argument { } } -public: + /** + * @brief Constructs argument from enum type + * @tparam T The enum type + * @param val The enum value + */ + template + void constructFromEnum(T&& val) { + static_assert(std::is_enum_v>, "T must be an enum type"); + + type_name = "enum"; + enum_type_name = getTypeName(); + + if (enum_type_name != "unknown_enum") { + values.push_back(static_cast(val)); + } else { + THROW("Unknown enum type for argument " + arg_name); + } + } - template - explicit inline Argument(const std::string name, T&& val) - : arg_name(std::move(name)) { - if constexpr (std::is_enum_v>) { - type_name = "enum"; // Enum types are stored as integers by default + /** + * @brief Constructs argument from vector type + * @tparam T The vector type + * @param val The vector value + */ + template + void constructFromVector(T&& val) { + static_assert(is_vector_type_v>, "T must be a vector type"); + + using ElementType = typename std::decay_t::value_type; + const std::string element_type_name = getTypeName(); + + if (element_type_name != "unknown") { + type_name = element_type_name; + is_vector = true; + values.reserve(val.size()); - enum_type_name = getTypeName(); - if (enum_type_name != "unknown_enum") { - values.push_back(static_cast(val)); - } else { - THROW("Unknown enum type for argument " + arg_name) - } - } else if constexpr (is_vector_type_v>) { - using ElementType = typename std::decay_t::value_type; - std::string element_type_name = getTypeName(); - if (element_type_name != "unknown") { - type_name = element_type_name; - is_vector = true; - values.reserve(val.size()); // Pre-allocate for better performance - for (auto&& v : std::forward(val)) { - values.push_back(static_cast(std::forward(v))); - } - } else { - THROW("Unknown vector element type for argument " + arg_name) + for (auto&& v : std::forward(val)) { + values.push_back(static_cast(std::forward(v))); } } else { - type_name = getTypeName(); - if (type_name != "unknown") { - if constexpr (std::is_same_v, const char*>) { - values.push_back(std::string(val)); - } else { - values.push_back(static_cast>(std::forward(val))); - } - } else { - THROW("Unknown type " + std::string(typeid(T).name()) + " for argument " + arg_name) - } + THROW("Unknown vector element type for argument " + arg_name); } } - // Used to store the feature key map - explicit inline Argument(std::string name, std::map val) - : arg_name(std::move(name)) { - type_name = "map_string"; - is_vector = true; - if (!val.empty()) { - values.reserve(val.size() * 2); // Pre-allocate for key-value pairs - for (auto&& pair : std::move(val)) { - values.push_back(std::move(pair.first)); // Push key - values.push_back(std::move(pair.second)); // Push value + /** + * @brief Constructs argument from basic type + * @tparam T The basic type + * @param val The value + */ + template + void constructFromBasicType(T&& val) { + type_name = getTypeName(); + + if (type_name != "unknown") { + if constexpr (std::is_same_v, const char*>) { + values.push_back(std::string(val)); + } else { + values.push_back(static_cast>(std::forward(val))); } + } else { + THROW("Unknown type " + std::string(typeid(T).name()) + " for argument " + arg_name); } } - // Used to store the shared_ptr - template - explicit inline Argument(std::string name, std::shared_ptr val) - : arg_name(std::move(name)) { + /** + * @brief Constructs argument from shared pointer type + * @tparam T The shared_ptr type + * @param val The shared_ptr value + */ + template + void constructFromSharedPtr(T&& val) { + static_assert(is_shared_ptr_v>, "T must be a shared_ptr type"); + type_name = "shared_ptr"; - // For MetadataReader case store an empty value // During deserialization the MetadataReader should be created and passed from the MasterGraph. if (arg_name == "meta_data_reader") { values.push_back(static_cast(0)); + } else { + THROW("Unsupported shared_ptr type for argument " + arg_name); } - // Could store additional shared_ptr metadata here if needed } - // Deduces the type of parameter of the argument - inline void extract_param(const RocalParameterType param_type, pParam parameter) { - if (param_type == RocalParameterType::DETERMINISTIC) { - enum_type_name = "SimpleParameter"; - } else if (param_type == RocalParameterType::RANDOM_UNIFORM) { - enum_type_name = "UniformRand"; - } else if (param_type == RocalParameterType::RANDOM_CUSTOM) { - enum_type_name = "CustomRand"; + /** + * @brief Constructs argument from string-to-string map type + * @tparam T The map type + * @param val The map value + */ + template + void constructFromMap(T&& val) { + static_assert(is_string_map_v>, "T must be a string-to-string map type"); + + type_name = "map_string"; + is_vector = true; + + if (!val.empty()) { + values.reserve(val.size() * 2); // Pre-allocate for key-value pairs + for (auto&& pair : std::forward(val)) { + values.push_back(std::move(pair.first)); // Push key + values.push_back(std::move(pair.second)); // Push value + } } - param = parameter; - is_parameter = true; } - // Constructor for FloatParam arguments - explicit inline Argument(std::string name, FloatParam* param) - : arg_name(std::move(name)) { - type_name = "float"; - if (param == nullptr) { + /** + * @brief Constructs argument from parameter type (FloatParam* or IntParam*) + * @tparam T The parameter pointer type + * @param val The parameter pointer value + */ + template + void constructFromParam(T&& val) { + static_assert(is_param_type_v>, "T must be a parameter pointer type"); + + using DecayedType = std::decay_t; + + if constexpr (std::is_same_v) { + type_name = "float"; + } else if constexpr (std::is_same_v) { + type_name = "int"; + } + + if (val == nullptr) { is_null_ptr = true; type_name = "nullptr"; return; } - extract_param(param->type, param); + + extractParam(val->type, val); } - // Constructor for IntParam arguments - explicit inline Argument(std::string name, IntParam* param) - : arg_name(std::move(name)) { - type_name = "int"; - if (param == nullptr) { - type_name = "nullptr"; - is_null_ptr = true; - return; + /** + * @brief Deduces the type of parameter of the argument + * @param param_type The type of the parameter + * @param parameter The parameter object + */ + void extractParam(RocalParameterType param_type, pParam parameter) { + switch (param_type) { + case RocalParameterType::DETERMINISTIC: + enum_type_name = "SimpleParameter"; + break; + case RocalParameterType::RANDOM_UNIFORM: + enum_type_name = "UniformRand"; + break; + case RocalParameterType::RANDOM_CUSTOM: + enum_type_name = "CustomRand"; + break; + default: + THROW("Unknown parameter type for argument " + arg_name); } - extract_param(param->type, param); + param = parameter; + is_parameter = true; } }; diff --git a/rocAL/include/pipeline/argument_types.h b/rocAL/include/pipeline/argument_types.h index 6ce1fcd99..218afb6f7 100644 --- a/rocAL/include/pipeline/argument_types.h +++ b/rocAL/include/pipeline/argument_types.h @@ -27,6 +27,7 @@ THE SOFTWARE. #include #include #include +#include "parameters/parameter_factory.h" // Enhanced type traits for argument processing (C++17 compatible) @@ -76,6 +77,29 @@ struct is_string_type : std::true_type {}; template constexpr bool is_string_type_v = is_string_type>::value; +// String-to-string map detection +template +struct is_string_map : std::false_type {}; + +template +struct is_string_map> : std::true_type {}; + +template +constexpr bool is_string_map_v = is_string_map>::value; + +// Parameter type detection +template +struct is_param_type : std::false_type {}; + +template <> +struct is_param_type : std::true_type {}; + +template <> +struct is_param_type : std::true_type {}; + +template +constexpr bool is_param_type_v = is_param_type>::value; + // SFINAE-based type checking (C++17 compatible) template using enable_if_basic_type = std::enable_if_t< @@ -107,7 +131,5 @@ constexpr const char* get_type_name() noexcept { else if constexpr (std::is_same_v) return "bool"; else if constexpr (std::is_same_v) return "string"; else if constexpr (std::is_same_v || std::is_same_v) return "char_str"; - else if constexpr (is_map_type_v) return "map"; - else if constexpr (is_shared_ptr_v) return "shared_ptr"; else return "unknown"; } From 2651138ee045c69ef5555a0ccde3a9b8062f512c Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Fri, 3 Oct 2025 04:05:31 -0500 Subject: [PATCH 021/118] Minor fix --- .../augmentations/geometry_augmentations/node_resize.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp b/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp index 4000b785f..2eb3358a3 100644 --- a/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp +++ b/rocAL/source/augmentations/geometry_augmentations/node_resize.cpp @@ -107,9 +107,9 @@ void ResizeNode::adjust_out_roi_size() { if (_max_height) _dst_height = std::min(_dst_height, _max_height); } } else if (_scaling_mode == ResizeScalingMode::DEFAULT) { - if ((!_dst_width) & _dst_height) { // Only height is passed + if ((!_dst_width) && _dst_height) { // Only height is passed _dst_width = std::lround(_src_width * (static_cast(_dst_height) / _src_height)); - } else if ((!_dst_height) & _dst_width) { // Only width is passed + } else if ((!_dst_height) && _dst_width) { // Only width is passed _dst_height = std::lround(_src_height * (static_cast(_dst_width) / _src_width)); } From 68dc5d3b7d28538b2174c410934360141db66dc2 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Fri, 3 Oct 2025 04:15:13 -0500 Subject: [PATCH 022/118] Remove unused includes --- rocAL/include/pipeline/enum_registry.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rocAL/include/pipeline/enum_registry.h b/rocAL/include/pipeline/enum_registry.h index f4b5a141d..ca5b08cc7 100644 --- a/rocAL/include/pipeline/enum_registry.h +++ b/rocAL/include/pipeline/enum_registry.h @@ -25,10 +25,6 @@ THE SOFTWARE. #include #include #include -#include -#include -#include -#include /*! * \brief Centralized enum registry for automatic enum type name management From da2ae16637b47275de32a72d5b338707c5b0f38f Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Fri, 3 Oct 2025 05:20:26 -0500 Subject: [PATCH 023/118] Add compiler keywords --- rocAL/include/pipeline/enum_registry.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rocAL/include/pipeline/enum_registry.h b/rocAL/include/pipeline/enum_registry.h index ca5b08cc7..62c5a9462 100644 --- a/rocAL/include/pipeline/enum_registry.h +++ b/rocAL/include/pipeline/enum_registry.h @@ -38,7 +38,7 @@ class EnumRegistry { * \brief Get the singleton instance of the enum registry * \return Reference to the singleton EnumRegistry instance */ - static EnumRegistry& getInstance() { + static EnumRegistry& getInstance() noexcept { static EnumRegistry instance; return instance; } @@ -81,7 +81,7 @@ class EnumRegistry { * \param type The type_index to check * \return true if the enum type is registered, false otherwise */ - bool isEnumRegistered(const std::type_index& type) const { + bool isEnumRegistered(const std::type_index& type) const noexcept { return _enum_map.find(type) != _enum_map.end(); } @@ -103,7 +103,7 @@ class EnumRegistry { * Usage: REGISTER_ENUM(MyEnumType) */ #define REGISTER_ENUM(EnumType) \ - static bool enum_registered_##EnumType = []() { \ + [[maybe_unused]] static bool enum_registered_##EnumType = []() { \ EnumRegistry::getInstance().registerEnum(#EnumType); \ return true; \ }(); From a1979c25791b68c8103fe7a4ac31e72cc858321b Mon Sep 17 00:00:00 2001 From: Fiona Gladwin <121928245+fgladwin@users.noreply.github.com> Date: Fri, 3 Oct 2025 16:07:36 +0530 Subject: [PATCH 024/118] Update rocAL/include/pipeline/argument.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/include/pipeline/argument.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index 193c489f1..52d452843 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -209,8 +209,8 @@ class Argument { if (!val.empty()) { values.reserve(val.size() * 2); // Pre-allocate for key-value pairs for (auto&& pair : std::forward(val)) { - values.push_back(std::move(pair.first)); // Push key - values.push_back(std::move(pair.second)); // Push value + values.push_back(pair.first); // Push key + values.push_back(pair.second); // Push value } } } From 48730bae508e614d708887e35c53be87ebe525f3 Mon Sep 17 00:00:00 2001 From: Fiona Gladwin <121928245+fgladwin@users.noreply.github.com> Date: Fri, 3 Oct 2025 16:08:29 +0530 Subject: [PATCH 025/118] Update rocAL/include/pipeline/argument.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/include/pipeline/argument.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index 52d452843..cda78f6ce 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -60,7 +60,7 @@ class Argument { bool is_vector = false; ///< True if the argument contains vector data bool is_parameter = false; ///< True if the argument is a parameter object bool is_null_ptr = false; ///< True if the argument represents a null pointer - std::vector values; ///< Storage for argument values (can change to std::variant later) + std::vector values; ///< Storage for argument values pParam param; ///< Parameter stored for parameter-type arguments // Constructors From 6b97bcbb19460a2fb648f83733f531fff2dd3784 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Sun, 5 Oct 2025 23:18:52 -0500 Subject: [PATCH 026/118] Minor change --- rocAL/include/pipeline/argument.h | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index cda78f6ce..ec54b5a07 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -42,21 +42,13 @@ THE SOFTWARE. * * This class encapsulates argument information for pipeline nodes, supporting * various data types including basic types, enums, vectors, maps, and parameters. - * - * The class provides type-safe storage and retrieval of arguments with support for: - * - Basic types (int, float, string, etc.) - * - Enum types with registry lookup - * - Vector containers - * - String-to-string maps - * - Shared pointers - * - Parameter objects (FloatParam, IntParam) */ class Argument { public: // Public member variables std::string arg_name; ///< Name of the argument std::string type_name; ///< Denotes the data type of the argument - std::string enum_type_name; ///< Denotes the name of the enum + std::string sub_type_name; ///< Denotes the name of the enum/ type of parameter bool is_vector = false; ///< True if the argument contains vector data bool is_parameter = false; ///< True if the argument is a parameter object bool is_null_ptr = false; ///< True if the argument represents a null pointer @@ -121,9 +113,9 @@ class Argument { static_assert(std::is_enum_v>, "T must be an enum type"); type_name = "enum"; - enum_type_name = getTypeName(); + sub_type_name = getTypeName(); - if (enum_type_name != "unknown_enum") { + if (sub_type_name != "unknown_enum") { values.push_back(static_cast(val)); } else { THROW("Unknown enum type for argument " + arg_name); @@ -249,13 +241,13 @@ class Argument { void extractParam(RocalParameterType param_type, pParam parameter) { switch (param_type) { case RocalParameterType::DETERMINISTIC: - enum_type_name = "SimpleParameter"; + sub_type_name = "SimpleParameter"; break; case RocalParameterType::RANDOM_UNIFORM: - enum_type_name = "UniformRand"; + sub_type_name = "UniformRand"; break; case RocalParameterType::RANDOM_CUSTOM: - enum_type_name = "CustomRand"; + sub_type_name = "CustomRand"; break; default: THROW("Unknown parameter type for argument " + arg_name); From 8f361bbc8038b288dbbbe3805159bbf67d1762c3 Mon Sep 17 00:00:00 2001 From: Fiona Gladwin <121928245+fgladwin@users.noreply.github.com> Date: Mon, 6 Oct 2025 10:17:56 +0530 Subject: [PATCH 027/118] Update rocAL/include/pipeline/argument.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/include/pipeline/argument.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index ec54b5a07..16a989761 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -139,7 +139,8 @@ class Argument { is_vector = true; values.reserve(val.size()); - for (auto&& v : std::forward(val)) { + auto&& local_val = std::forward(val); + for (auto&& v : local_val) { values.push_back(static_cast(std::forward(v))); } } else { From c6212ca46de0179ae96514ea96fa98c1a6af9022 Mon Sep 17 00:00:00 2001 From: Fiona Gladwin <121928245+fgladwin@users.noreply.github.com> Date: Mon, 6 Oct 2025 10:18:04 +0530 Subject: [PATCH 028/118] Update rocAL/include/pipeline/argument.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/include/pipeline/argument.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index 16a989761..502dab5f9 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -201,7 +201,8 @@ class Argument { if (!val.empty()) { values.reserve(val.size() * 2); // Pre-allocate for key-value pairs - for (auto&& pair : std::forward(val)) { + auto&& forwarded_val = std::forward(val); + for (auto&& pair : forwarded_val) { values.push_back(pair.first); // Push key values.push_back(pair.second); // Push value } From 57dfa73a1b3dd0248b5e7141440b862bff797ed1 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Sun, 5 Oct 2025 23:58:06 -0500 Subject: [PATCH 029/118] Minor change --- rocAL/include/pipeline/argument.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index 502dab5f9..4c960f51c 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -201,8 +201,8 @@ class Argument { if (!val.empty()) { values.reserve(val.size() * 2); // Pre-allocate for key-value pairs - auto&& forwarded_val = std::forward(val); - for (auto&& pair : forwarded_val) { + auto&& string_map = std::forward(val); + for (auto&& pair : string_map) { values.push_back(pair.first); // Push key values.push_back(pair.second); // Push value } From 55640dde06fb5a47233175f1c4f3a62df7574642 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Mon, 6 Oct 2025 08:56:05 -0500 Subject: [PATCH 030/118] Fix shared pointer fetching --- rocAL/include/pipeline/argument.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rocAL/include/pipeline/argument.h b/rocAL/include/pipeline/argument.h index 4c960f51c..1c0530bc9 100644 --- a/rocAL/include/pipeline/argument.h +++ b/rocAL/include/pipeline/argument.h @@ -178,10 +178,11 @@ class Argument { static_assert(is_shared_ptr_v>, "T must be a shared_ptr type"); type_name = "shared_ptr"; - // For MetadataReader case store an empty value - // During deserialization the MetadataReader should be created and passed from the MasterGraph. + // For MetaDataReader, mark as an external reference to be resolved during deserialization. + // The actual MetaDataReader instance should be created and provided by the MasterGraph/Pipeline. if (arg_name == "meta_data_reader") { - values.push_back(static_cast(0)); + sub_type_name = "MetaDataReader"; + // No serialized payload for external references. } else { THROW("Unsupported shared_ptr type for argument " + arg_name); } From f0a5e49caf4eeb04d26223cc6e48b9e63ea2d5a3 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Mon, 6 Oct 2025 08:56:20 -0500 Subject: [PATCH 031/118] Minor fix --- rocAL/include/pipeline/node.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index b0d22262e..2234a0128 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -27,7 +27,7 @@ THE SOFTWARE. #include "pipeline/graph.h" #include "meta_data/meta_data_graph.h" #include "pipeline/tensor.h" -#include "argument.h" +#include "pipeline/argument.h" class Node { public: From fa66d0b714afae19ca5b00947a5532db29ab4859 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Mon, 6 Oct 2025 11:16:38 -0500 Subject: [PATCH 032/118] Minor fix --- rocAL/include/pipeline/master_graph.h | 4 ++-- rocAL/include/pipeline/pipeline_operator.h | 19 +++++++++++-------- rocAL/include/pipeline/tensor.h | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 06086e3b2..50e98ad47 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -242,8 +242,8 @@ class MasterGraph { BoxEncoderGpu *_box_encoder_gpu = nullptr; #endif TimingDbg _rb_block_if_empty_time, _rb_block_if_full_time; - std::vector> _pipeline_operators; - int _op_idx = 0; + std::vector> _pipeline_operators; // Contains the info of all the operators present in the pipeline + int _op_idx = 0; // Operator index used to uniquely name PipelineOperator entries }; template diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index b5b148e95..6b4b79df9 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -25,21 +25,24 @@ THE SOFTWARE. #include #include "pipeline/node.h" -// Stores the information for the operator in the pipeline +// Represents an operator in the pipeline class PipelineOperator { public: + // Constructor to initialize the operator explicit inline PipelineOperator(std::string op_name, std::string op_module_name, std::shared_ptr op_node = nullptr) { - operator_name = op_name; - module_name = op_module_name; - node = op_node; + operator_name = op_name; // Set the operator's name + module_name = op_module_name; // Set the type/category of the operator + node = op_node; // Optional reference to the underlying node object } + + // Set the list of arguments associated with this operator void set_arguments(std::vector op_arguments) { arguments = op_arguments; } - std::string operator_name; // Name of the Node/operator - std::string module_name; // Denotes the type of operator i.e loader/reader/augmentation - std::vector arguments; - std::shared_ptr node; + std::string operator_name; // Name of the operator (e.g., "ResizeNode") + std::string module_name; // Category of the operator (e.g., "loader", "augmentation" or "reader") + std::vector arguments; // List of arguments/configurations for the operator + std::shared_ptr node; // Pointer to the associated computational graph node }; diff --git a/rocAL/include/pipeline/tensor.h b/rocAL/include/pipeline/tensor.h index 097d2df05..1c1988e28 100644 --- a/rocAL/include/pipeline/tensor.h +++ b/rocAL/include/pipeline/tensor.h @@ -385,7 +385,7 @@ class Tensor : public rocalTensor { TensorInfo _info; //!< The structure holding the info related to the stored OpenVX tensor vx_context _context = nullptr; vx_tensor _vx_roi_handle = nullptr; //!< The OpenVX tensor for ROI - inline static int _tensor_idx = 0; + inline static int _tensor_idx = 0; // Tensor index used to uniquely name Tensors std::string _tensor_name; }; From 5237ff2c124f5c41ac6009c14ac74ad0d8e4ca9c Mon Sep 17 00:00:00 2001 From: Fiona Gladwin <121928245+fgladwin@users.noreply.github.com> Date: Tue, 7 Oct 2025 12:22:42 +0530 Subject: [PATCH 033/118] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/include/pipeline/master_graph.h | 2 +- rocAL/source/loaders/image/node_image_loader.cpp | 2 +- rocAL/source/pipeline/master_graph.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 50e98ad47..9e8e00fa9 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -251,7 +251,7 @@ std::shared_ptr MasterGraph::add_node(const std::vector &inputs, co auto node = std::make_shared(inputs, outputs); _nodes.push_back(node); - // Add each opertor to the pipeline operators list + // Add each operator to the pipeline operators list _pipeline_operators.push_back(std::make_shared(node->node_name() + "_" + std::to_string(_op_idx++), "augmentation", node)); for (auto &input : inputs) { diff --git a/rocAL/source/loaders/image/node_image_loader.cpp b/rocAL/source/loaders/image/node_image_loader.cpp index 66d04057c..755a74cdc 100644 --- a/rocAL/source/loaders/image/node_image_loader.cpp +++ b/rocAL/source/loaders/image/node_image_loader.cpp @@ -55,7 +55,7 @@ void ImageLoaderNode::init(unsigned internal_shard_count, unsigned cpu_num_threa std::array arg_names = { "internal_shard_count", "cpu_num_threads", "source_path", "json_path", "feature_key_map", "storage_type", "decoder_type", - "shuffle", "loop", "load_batch_count", "mem_type","meta_data_reader", "decoder_keep_orig", + "shuffle", "loop", "load_batch_count", "mem_type", "meta_data_reader", "decoder_keep_orig", "last_batch_policy", "pad_last_batch_repeated", "stick_to_shard", "shard_size", "file_prefix", "sequence_length", "step", "stride", "external_file_mode", "index_path" diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 8eb902904..9e712e96a 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1269,7 +1269,7 @@ TensorListVector* MasterGraph::create_label_reader(const char *source_path, Meta _meta_data_reader = create_meta_data_reader(config, _augmented_meta_data); _meta_data_reader->read_all(source_path); - // Add each opertor to the pipeline operators list + // Add each operator to the pipeline operators list auto reader_op = std::make_shared("LabelReader_" + std::to_string(_op_idx++), "reader"); // Add all arguments as part of the operator From 58d98fed94e0c3d03bac560bea09fa84a72a458b Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 7 Oct 2025 04:35:42 -0500 Subject: [PATCH 034/118] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 218aa4fe9..7ce0e7ee8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro ### Added * Added JAX iterator support in rocAL +* Refactor external enum usage in rocAL, to maintain separation between external and internal enums. ## rocAL 2.3.0 for ROCm 7.0.0 From ae8664820dc58adeb11d2cc713b2ae667d13eaa0 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 7 Oct 2025 04:37:34 -0500 Subject: [PATCH 035/118] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ce0e7ee8..1128d50ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro ### Added * Added JAX iterator support in rocAL * Refactor external enum usage in rocAL, to maintain separation between external and internal enums. +* Add support to register all the enums required for serialization using newly introduced enum registry. ## rocAL 2.3.0 for ROCm 7.0.0 From bef321b8a4194f57377d12f289cb6363bc5b02c9 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 8 Oct 2025 08:39:08 -0500 Subject: [PATCH 036/118] Add all serialization code to pipeline serializer Remove the use of pipeline operator --- rocAL/include/pipeline/master_graph.h | 4 +- rocAL/include/pipeline/node.h | 6 +- rocAL/include/pipeline/pipeline_operator.h | 20 ++- rocAL/include/pipeline/pipeline_serializer.h | 2 + rocAL/source/pipeline/master_graph.cpp | 4 +- rocAL/source/pipeline/pipeline_operator.cpp | 150 ------------------ rocAL/source/pipeline/pipeline_serializer.cpp | 133 ++++++++++++++-- 7 files changed, 148 insertions(+), 171 deletions(-) delete mode 100644 rocAL/source/pipeline/pipeline_operator.cpp diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 88fe4a915..ac13a54a2 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -255,7 +255,7 @@ std::shared_ptr MasterGraph::add_node(const std::vector &inputs, co auto node = std::make_shared(inputs, outputs); _nodes.push_back(node); - // Add each opertor to the pipeline operators list + // Add each operator to the pipeline operators list _pipeline_operators.push_back(std::make_shared(node->node_name() + "_" + std::to_string(_op_idx++), "augmentation", node)); for (auto &input : inputs) { @@ -299,7 +299,7 @@ inline std::shared_ptr MasterGraph::add_node(const std::vector< node->set_graph_id(_loaders_count++); _root_nodes.push_back(node); - // Add each opertor to the pipeline operators list + // Add each operator to the pipeline operators list _pipeline_operators.push_back(std::make_shared(node->node_name() + "_" + std::to_string(_op_idx++), "loader", node)); for (auto &output : outputs) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 1865f4ec0..060c397e3 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -37,8 +37,8 @@ class Node { virtual ~Node(); void create(std::shared_ptr graph); void update_parameters(); - std::vector input() { return _inputs; }; - std::vector output() { return _outputs; }; + const std::vector& input() const { return _inputs; } + const std::vector& output() const { return _outputs; } void add_next(const std::shared_ptr &node); // Adds the Node next to the current Node void add_previous(const std::shared_ptr &node); // Adds the Node preceding the current Node void release(); @@ -50,7 +50,7 @@ class Node { void set_graph_id(int id) { _graph_id = id; } int get_graph_id() { return _graph_id; } virtual std::string node_name() { return ""; } - std::vector get_args_list() { return _args; } + std::vector& get_args_list() { return _args; } protected: virtual void create_node() = 0; diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index 17aa8462f..4c39e8c6b 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -38,12 +38,26 @@ class PipelineOperator { } // Set the list of arguments associated with this operator - void set_arguments(std::vector op_arguments) { + void set_arguments(std::vector& op_arguments) { arguments = op_arguments; } - void serialize_pipeop_args_to_protobuf(rocal_proto::OperatorDef *opdef); - void serialize_pipeop_inputs_and_outputs_to_protobuf(rocal_proto::OperatorDef *opdef); + const std::vector& get_arguments() { + if (this->module_name == "reader") { + return this->arguments; + } else { + return this->node->get_args_list(); + } + } + + const std::vector& get_inputs() { + return this->node->input(); + } + + const std::vector& get_outputs() { + return this->node->output(); + } + std::string operator_name; // Name of the operator (e.g., "ResizeNode") std::string module_name; // Category of the operator (e.g., "loader", "augmentation" or "reader") std::vector arguments; // List of arguments/configurations for the operator diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h index 382f0f44c..b8e82e0b9 100644 --- a/rocAL/include/pipeline/pipeline_serializer.h +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -24,6 +24,7 @@ THE SOFTWARE. #include #include "pipeline/pipeline_operator.h" +#include "rocal.pb.h" class PipelineSerializer { public: @@ -50,6 +51,7 @@ class PipelineSerializer { void serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth); void serialize_output_tensors(TensorList& output_tensors_list); void serialize_operators(std::vector>& operators); + void serialize_pipeop_arguments(const std::vector& arguments_list, rocal_proto::OperatorDef *opdef); /** * @brief Deserialize a rocAL pipeline from a file diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index d1535f695..cd4060296 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1269,7 +1269,7 @@ TensorListVector* MasterGraph::create_label_reader(const char *source_path, Meta _meta_data_reader = create_meta_data_reader(config, _augmented_meta_data); _meta_data_reader->read_all(source_path); - // Add each opertor to the pipeline operators list + // Add each operator to the pipeline operators list auto reader_op = std::make_shared("LabelReader_" + std::to_string(_op_idx++), "reader"); // Add all arguments as part of the operator @@ -1887,7 +1887,7 @@ void MasterGraph::feed_external_input(const std::vector& input_imag void MasterGraph::serialize(size_t &serialized_string_size) { _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth); _pipeline_serializer.serialize_operators(_pipeline_operators); - _pipeline_serializer.serialize_output_tensors(_internal_tensor_list); + _pipeline_serializer.serialize_output_tensors(_output_tensor_list); _pipeline_serializer.serialize_to_string(_serialized_pipeline); serialized_string_size = _serialized_pipeline.size(); } diff --git a/rocAL/source/pipeline/pipeline_operator.cpp b/rocAL/source/pipeline/pipeline_operator.cpp deleted file mode 100644 index fc5b64e39..000000000 --- a/rocAL/source/pipeline/pipeline_operator.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "pipeline/pipeline_operator.h" - -void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input = false) { - in_out_proto->set_name(tensor->tensor_name()); - in_out_proto->set_device(static_cast(tensor->info().mem_type())); - in_out_proto->set_dtype(static_cast(tensor->info().data_type())); - in_out_proto->set_layout(static_cast(tensor->info().layout())); - in_out_proto->set_color_format(static_cast(tensor->info().color_format())); - for (auto &dim : tensor->info().dims()) - in_out_proto->add_dims(dim); - in_out_proto->set_num_dims(tensor->info().num_of_dims()); - in_out_proto->set_is_argument_input(is_input); -} - -void PipelineOperator::serialize_pipeop_inputs_and_outputs_to_protobuf(rocal_proto::OperatorDef *opdef) { - if (this->module_name == "reader") - return; // Readers do not have tensor outputs, hence return - - // Serialize input tensors to protobuffers - for (auto &node_input : this->node->input()) { - rocal_proto::InputOutput *input = opdef->add_inputs(); - set_tensor_proto(input, node_input, true); - } - - // Serialize output tensors to protobuffers - for (auto &node_output : this->node->output()) { - rocal_proto::InputOutput *output = opdef->add_outputs(); - set_tensor_proto(output, node_output); - } -} - -void PipelineOperator::serialize_pipeop_args_to_protobuf(rocal_proto::OperatorDef *opdef) { - std::vector arguments_list; - - if (this->module_name == "reader") { - arguments_list = this->arguments; - } else { - arguments_list = this->node->get_args_list(); - } - // Iterate through each argument to store in the protobuffers - for (auto &op_arg : arguments_list) { - rocal_proto::Arguments *arg = opdef->add_args(); - arg->set_name(op_arg.arg_name); - arg->set_type(op_arg.type_name); - arg->set_is_vector(op_arg.is_vector); - - if (op_arg.type_name == "nullptr") continue; - if (op_arg.enum_type_name != "") - arg->set_instance_name(op_arg.enum_type_name); - - if (op_arg.is_parameter) { - // TODO - Will be enabled later - // rocal_proto::Parameter *param = arg->mutable_param(); - // serialize_parameter_to_protobuf(param, op_arg); - } else if (op_arg.type_name == "enum") { - rocal_proto::EnumType* enum_arg = arg->mutable_enum_value(); - enum_arg->set_name(op_arg.enum_type_name); - enum_arg->set_value(std::any_cast(op_arg.values[0])); - } else { - // Scalars go to the flat repeated fields; vectors go to repeated *Vector messages - if (op_arg.is_vector) { - if (op_arg.values.empty()) { - // Represent empty vector by adding an empty vector message of the right type - if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr" - || op_arg.type_name == "unsigned" || op_arg.type_name == "size_t") { - static_cast(arg->add_int_vectors()); - } else if (op_arg.type_name == "float") { - static_cast(arg->add_float_vectors()); - } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string" - || op_arg.type_name == "map_string") { - static_cast(arg->add_string_vectors()); - } else { - THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); - } - } else { - if (op_arg.type_name == "int" || op_arg.type_name == "unsigned" || op_arg.type_name == "size_t") { - auto *vec = arg->add_int_vectors(); - for (auto &v : op_arg.values) { - // Map unsigned/size_t to int64 for IntVector as per spec (only Int/Float/String vectors permitted) - if (op_arg.type_name == "unsigned") { - vec->add_values(static_cast(std::any_cast(v))); - } else if (op_arg.type_name == "size_t") { - vec->add_values(static_cast(std::any_cast(v))); - } else { - vec->add_values(static_cast(std::any_cast(v))); - } - } - } else if (op_arg.type_name == "float") { - auto *vec = arg->add_float_vectors(); - for (auto &v : op_arg.values) { - vec->add_values(std::any_cast(v)); - } - } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string" - || op_arg.type_name == "map_string") { - auto *vec = arg->add_string_vectors(); - for (auto &v : op_arg.values) { - vec->add_values(std::any_cast(v)); - } - } else { - THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); - } - } - } else { - // Scalar path (use flat repeated fields) - if (op_arg.values.size() > 1) { - ERR("Argument has more than one value, is_vector should be set to true") - } - for (auto &v : op_arg.values) { - if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr") { - arg->add_ints(std::any_cast(v)); - } else if (op_arg.type_name == "float") { - arg->add_floats(std::any_cast(v)); - } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string") { - arg->add_strings(std::any_cast(v)); - } else if (op_arg.type_name == "bool") { - arg->add_bools(std::any_cast(v)); - } else if (op_arg.type_name == "unsigned") { - arg->add_uints(std::any_cast(v)); - } else if (op_arg.type_name == "size_t") { - arg->add_uints(std::any_cast(v)); - } else { - THROW("Invalid type specified for the Argument " + op_arg.arg_name); - } - } - } - } - } -} diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index bb4412fe4..55e94faed 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -34,6 +34,110 @@ void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t ba _pipeline.set_prefetch_queue_depth(prefetch_queue_depth); } +void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input = false) { + in_out_proto->set_name(tensor->tensor_name()); + in_out_proto->set_device(static_cast(tensor->info().mem_type())); + in_out_proto->set_dtype(static_cast(tensor->info().data_type())); + in_out_proto->set_layout(static_cast(tensor->info().layout())); + in_out_proto->set_color_format(static_cast(tensor->info().color_format())); + for (auto &dim : tensor->info().dims()) + in_out_proto->add_dims(dim); + in_out_proto->set_num_dims(tensor->info().num_of_dims()); + in_out_proto->set_is_argument_input(is_input); +} + +void PipelineSerializer::serialize_pipeop_arguments(const std::vector& arguments_list, rocal_proto::OperatorDef *opdef) { + + // Iterate through each argument to store in the protobuffers + for (auto &op_arg : arguments_list) { + rocal_proto::Arguments *arg = opdef->add_args(); + arg->set_name(op_arg.arg_name); + arg->set_type(op_arg.type_name); + arg->set_is_vector(op_arg.is_vector); + + if (op_arg.type_name == "nullptr") continue; + if (op_arg.sub_type_name != "") + arg->set_instance_name(op_arg.sub_type_name); + + if (op_arg.is_parameter) { + // TODO - Will be enabled later + // rocal_proto::Parameter *param = arg->mutable_param(); + // serialize_parameter_to_protobuf(param, op_arg); + } else if (op_arg.type_name == "enum") { + rocal_proto::EnumType* enum_arg = arg->mutable_enum_value(); + enum_arg->set_name(op_arg.sub_type_name); + enum_arg->set_value(std::any_cast(op_arg.values[0])); + } else { + // Scalars go to the flat repeated fields; vectors go to repeated *Vector messages + if (op_arg.is_vector) { + if (op_arg.values.empty()) { + // Represent empty vector by adding an empty vector message of the right type + if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr" + || op_arg.type_name == "unsigned" || op_arg.type_name == "size_t") { + static_cast(arg->add_int_vectors()); + } else if (op_arg.type_name == "float") { + static_cast(arg->add_float_vectors()); + } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string" + || op_arg.type_name == "map_string") { + static_cast(arg->add_string_vectors()); + } else { + THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); + } + } else { + if (op_arg.type_name == "int" || op_arg.type_name == "unsigned" || op_arg.type_name == "size_t") { + auto *vec = arg->add_int_vectors(); + for (auto &v : op_arg.values) { + // Map unsigned/size_t to int64 for IntVector as per spec (only Int/Float/String vectors permitted) + if (op_arg.type_name == "unsigned") { + vec->add_values(static_cast(std::any_cast(v))); + } else if (op_arg.type_name == "size_t") { + vec->add_values(static_cast(std::any_cast(v))); + } else { + vec->add_values(static_cast(std::any_cast(v))); + } + } + } else if (op_arg.type_name == "float") { + auto *vec = arg->add_float_vectors(); + for (auto &v : op_arg.values) { + vec->add_values(std::any_cast(v)); + } + } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string" + || op_arg.type_name == "map_string") { + auto *vec = arg->add_string_vectors(); + for (auto &v : op_arg.values) { + vec->add_values(std::any_cast(v)); + } + } else { + THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); + } + } + } else { + // Scalar path (use flat repeated fields) + if (op_arg.values.size() > 1) { + ERR("Argument has more than one value, is_vector should be set to true") + } + for (auto &v : op_arg.values) { + if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr") { + arg->add_ints(std::any_cast(v)); + } else if (op_arg.type_name == "float") { + arg->add_floats(std::any_cast(v)); + } else if (op_arg.type_name == "char_str" || op_arg.type_name == "string") { + arg->add_strings(std::any_cast(v)); + } else if (op_arg.type_name == "bool") { + arg->add_bools(std::any_cast(v)); + } else if (op_arg.type_name == "unsigned") { + arg->add_uints(std::any_cast(v)); + } else if (op_arg.type_name == "size_t") { + arg->add_uints(std::any_cast(v)); + } else { + THROW("Invalid type specified for the Argument " + op_arg.arg_name); + } + } + } + } + } +} + void PipelineSerializer::serialize_operators(std::vector>& operators) { // Serialize all operators for (auto &pipe_op : operators) { @@ -41,8 +145,23 @@ void PipelineSerializer::serialize_operators(std::vectorset_name(pipe_op->operator_name); op->set_module_name(pipe_op->module_name); // Add support to add each argument in the operator - pipe_op->serialize_pipeop_args_to_protobuf(op); - pipe_op->serialize_pipeop_inputs_and_outputs_to_protobuf(op); + serialize_pipeop_arguments(pipe_op->get_arguments(), op); + // serialize_pipeop_inputs_and_outputs(pipe_op->get_inputs(), pipe_op->get_outputs()); + + if (pipe_op->module_name == "reader") + continue; // Readers do not have tensor outputs, hence return + + // Serialize input tensors to protobuffers + for (auto &node_input : pipe_op->get_inputs()) { + rocal_proto::InputOutput *input = op->add_inputs(); + set_tensor_proto(input, node_input, true); + } + + // Serialize output tensors to protobuffers + for (auto &node_output : pipe_op->get_outputs()) { + rocal_proto::InputOutput *output = op->add_outputs(); + set_tensor_proto(output, node_output); + } } } @@ -52,14 +171,6 @@ void PipelineSerializer::serialize_output_tensors(TensorList& output_tensors_lis for (size_t idx = 0; idx < output_tensors_list.size(); idx++) { rocal_proto::InputOutput *output = _pipeline.add_pipe_outputs(); auto pipe_output = output_tensors_list[idx]; - output->set_name(pipe_output->tensor_name()); - output->set_device(static_cast(pipe_output->info().mem_type())); - output->set_dtype(static_cast(pipe_output->info().data_type())); - output->set_layout(static_cast(pipe_output->info().layout())); - output->set_color_format(static_cast(pipe_output->info().color_format())); - for (auto& dim : pipe_output->info().dims()) - output->add_dims(dim); - output->set_num_dims(pipe_output->info().num_of_dims()); - output->set_is_argument_input(false); + set_tensor_proto(output, pipe_output, false); } } From bbc96afacffddb1f49c0af2c49173b4a52981b5b Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 8 Oct 2025 10:29:48 -0500 Subject: [PATCH 037/118] Revert fix --- rocAL/source/pipeline/master_graph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index cd4060296..28aa5b2b8 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1887,7 +1887,7 @@ void MasterGraph::feed_external_input(const std::vector& input_imag void MasterGraph::serialize(size_t &serialized_string_size) { _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth); _pipeline_serializer.serialize_operators(_pipeline_operators); - _pipeline_serializer.serialize_output_tensors(_output_tensor_list); + _pipeline_serializer.serialize_output_tensors(_internal_tensor_list); _pipeline_serializer.serialize_to_string(_serialized_pipeline); serialized_string_size = _serialized_pipeline.size(); } From c4101fc732d390d607b4cc9dce8b8022d7444fcb Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:57:47 +0530 Subject: [PATCH 038/118] Update CHANGELOG.md --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aca788004..a96760e05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,17 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/projects/rocAL/](https://rocm.docs.amd.com/projects/rocAL/en/latest/). +## rocAL 2.5.0 (Unreleased) + +### Changes +* Refactor external enum usage in rocAL, to maintain separation between external and internal enums. +* Introduced the following enums ResizeScalingMode, ResizeInterpolationType, MelScaleFormula, AudioBorderType, OutOfBoundsPolicy in commons.h. + ## rocAL 2.4.0 for ROCm 7.1.0 ### Added * Added JAX iterator support in rocAL * rocJPEG - Fused Crop decoding support -* Refactor external enum usage in rocAL, to maintain separation between external and internal enum. ### Changes * CropResize - updates and fixes From b66804313ba733688c5dd985ee5b5ff48df211fa Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:59:54 +0530 Subject: [PATCH 039/118] Update CHANGELOG.md --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aca788004..5b9be29ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,21 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/projects/rocAL/](https://rocm.docs.amd.com/projects/rocAL/en/latest/). +## rocAL 2.5.0 (Unreleased) + +### Added +* Introduce enum registry to register all the enums present in rocAL. + +### Changes +* Refactor external enum usage in rocAL, to maintain separation between external and internal enums. +* Introduced the following enums ResizeScalingMode, ResizeInterpolationType, MelScaleFormula, AudioBorderType, OutOfBoundsPolicy in commons.h. +* + ## rocAL 2.4.0 for ROCm 7.1.0 ### Added * Added JAX iterator support in rocAL * rocJPEG - Fused Crop decoding support -* Refactor external enum usage in rocAL, to maintain separation between external and internal enum. ### Changes * CropResize - updates and fixes From 877bee0f4a339c6dbfeb56853ad34c267da2989e Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Thu, 9 Oct 2025 16:00:17 +0530 Subject: [PATCH 040/118] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b9be29ff..9aed3bd29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro ### Changes * Refactor external enum usage in rocAL, to maintain separation between external and internal enums. * Introduced the following enums ResizeScalingMode, ResizeInterpolationType, MelScaleFormula, AudioBorderType, OutOfBoundsPolicy in commons.h. -* ## rocAL 2.4.0 for ROCm 7.1.0 From 43636be018bae8a38f4381b4a01ae7a23f63caad Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 9 Oct 2025 05:35:12 -0500 Subject: [PATCH 041/118] Add comments and doc description --- rocAL/include/api/rocal_api.h | 21 ++++++++- rocAL/include/pipeline/master_graph.h | 9 +++- rocAL/include/pipeline/pipeline_operator.h | 15 ++++++- rocAL/include/pipeline/pipeline_serializer.h | 44 ++++++++----------- rocAL/source/api/rocal_api.cpp | 4 +- rocAL/source/pipeline/pipeline_serializer.cpp | 2 - 6 files changed, 61 insertions(+), 34 deletions(-) diff --git a/rocAL/include/api/rocal_api.h b/rocAL/include/api/rocal_api.h index 12530d4aa..1e322f174 100644 --- a/rocAL/include/api/rocal_api.h +++ b/rocAL/include/api/rocal_api.h @@ -109,8 +109,27 @@ extern "C" RocalStatus ROCAL_API_CALL rocalRun(RocalContext context); */ extern "C" RocalStatus ROCAL_API_CALL rocalRelease(RocalContext rocal_context); +/*! + * \brief Serialize the current pipeline into an opaque binary string. + * \ingroup group_rocal + * \param [in] rocal_context the rocAL context + * \param [out] serialized_string_size number of bytes in the serialized string + * \return A \ref RocalStatus - A status code indicating the success or failure. + */ extern "C" RocalStatus ROCAL_API_CALL rocalSerialize(RocalContext rocal_context, size_t &serialized_string_size); -extern "C" RocalStatus ROCAL_API_CALL rocalGetSerializedString(RocalContext rocal_context, const char* serialized_string); +/*! + * \brief Copy the last serialized pipeline string into a user buffer. + * \ingroup group_rocal + * + * This API copies the serialized pipeline string produced by rocalSerialize() + * into the user-provided buffer. The buffer must be pre-allocated with size + * at least serialized_string_size + 1 bytes to accommodate the null terminator. + * + * \param [in] rocal_context the rocAL context + * \param [out] serialized_string destination buffer to receive the serialized string (null-terminated) + * \return A \ref RocalStatus - A status code indicating the success or failure. + */ +extern "C" RocalStatus ROCAL_API_CALL rocalGetSerializedString(RocalContext rocal_context, char* serialized_string); #endif diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index ac13a54a2..86f1e2227 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -153,7 +153,10 @@ class MasterGraph { RocalTensorlayout layout, bool eos); void set_external_source_reader_flag() { _external_source_reader = true; } size_t bounding_box_batch_count(pMetaDataBatch meta_data_batch); - void serialize(size_t &serialized_string_size); + /** + * Serialize API + */ + void serialize(size_t &serialized_string_size); // Serialize the current pipeline to an internal string and return its size. std::string get_serialized_string() { return _serialized_pipeline; } #if ENABLE_OPENCL cl_command_queue get_ocl_cmd_q() { return _device.resources()->cmd_queue; } @@ -246,8 +249,10 @@ class MasterGraph { TimingDbg _rb_block_if_empty_time, _rb_block_if_full_time; std::vector> _pipeline_operators; // Contains the info of all the operators present in the pipeline int _op_idx = 0; // Operator index used to uniquely name PipelineOperator entries + // Helper used to build protobuf payloads of the pipeline PipelineSerializer _pipeline_serializer; - std::string _serialized_pipeline; // Stores the serialized string of the pipeline + // Stores the serialized binary string representation of the pipeline + std::string _serialized_pipeline; }; template diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index 4c39e8c6b..38232896f 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -24,7 +24,6 @@ THE SOFTWARE. #include #include "pipeline/node.h" -#include "rocal.pb.h" // Represents an operator in the pipeline class PipelineOperator { @@ -38,10 +37,16 @@ class PipelineOperator { } // Set the list of arguments associated with this operator - void set_arguments(std::vector& op_arguments) { + void set_arguments(const std::vector& op_arguments) { arguments = op_arguments; } + /** + * Get the argument list for this operator. + * + * For reader modules, arguments are stored directly on the operator. + * For augmentation operators, the arguments are maintained by the underlying Node. + */ const std::vector& get_arguments() { if (this->module_name == "reader") { return this->arguments; @@ -50,10 +55,16 @@ class PipelineOperator { } } + /** + * Get the input tensors connected to the underlying node. + */ const std::vector& get_inputs() { return this->node->input(); } + /** + * Get the output tensors produced by the underlying node. + */ const std::vector& get_outputs() { return this->node->output(); } diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h index b8e82e0b9..511e268fb 100644 --- a/rocAL/include/pipeline/pipeline_serializer.h +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -23,9 +23,17 @@ THE SOFTWARE. #pragma once #include +#include +#include #include "pipeline/pipeline_operator.h" #include "rocal.pb.h" +/** + * @brief Helper to serialize a built rocAL pipeline into a protobuf-based payload. + * + * This class gathers top-level pipeline configuration, operators (names, modules, + * arguments) and tensors (inputs/outputs) and writes them into rocal_proto::PipelineDef. + */ class PipelineSerializer { public: PipelineSerializer() {} @@ -33,41 +41,27 @@ class PipelineSerializer { // Serialization methods /** - * @brief Serialize a rocAL pipeline to a file - * @param context The rocAL context containing the pipeline - * @param file_path Path to save the serialized pipeline - * @return RocalStatus indicating success or failure - */ - void serialize_to_file(const std::string& file_path); - - /** - * @brief Serialize a rocAL pipeline to a string - * @param context The rocAL context containing the pipeline + * @brief Serialize the current PipelineDef into a binary string. * @param serialized_string Output string containing the serialized pipeline - * @return RocalStatus indicating success or failure */ void serialize_to_string(std::string& serialized_string); + /** + * @brief Serialize global pipeline configuration. + */ void serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth); + /** + * @brief Serialize pipeline output tensors (shape, dtype, device, layout). + */ void serialize_output_tensors(TensorList& output_tensors_list); - void serialize_operators(std::vector>& operators); - void serialize_pipeop_arguments(const std::vector& arguments_list, rocal_proto::OperatorDef *opdef); - /** - * @brief Deserialize a rocAL pipeline from a file - * @param file_path Path to the serialized pipeline file - * @param context Output context containing the deserialized pipeline - * @return RocalStatus indicating success or failure + * @brief Serialize all operators, their arguments, and IO tensors. */ - // RocalStatus deserialize_from_file(const std::string& file_path, Context** context); - + void serialize_operators(std::vector>& operators); /** - * @brief Deserialize a rocAL pipeline from a string - * @param serialized_string String containing the serialized pipeline - * @param context Output context containing the deserialized pipeline - * @return RocalStatus indicating success or failure + * @brief Serialize a single operator's arguments into protobuf. */ - // RocalStatus deserialize_from_string(const std::string& serialized_string, Context** context); + void serialize_pipeop_arguments(const std::vector& arguments_list, rocal_proto::OperatorDef *opdef); protected: rocal_proto::PipelineDef _pipeline; diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index 0ab793bfa..41b797356 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -120,7 +120,7 @@ rocalSerialize(RocalContext rocal_context, size_t &serialized_string_size) { } RocalStatus ROCAL_API_CALL -rocalGetSerializedString(RocalContext rocal_context, const char* serialized_string) { +rocalGetSerializedString(RocalContext rocal_context, char* serialized_string) { auto context = static_cast(rocal_context); try { if (!serialized_string) { @@ -130,7 +130,7 @@ rocalGetSerializedString(RocalContext rocal_context, const char* serialized_stri auto serialize_pipe_string = context->master_graph->get_serialized_string(); if (serialize_pipe_string.empty()) THROW("Serialized string is empty, Invoke rocalSerialize before obtaining the string") - std::memcpy(const_cast(serialized_string), serialize_pipe_string.c_str(), serialize_pipe_string.size() + 1); + std::memcpy(serialized_string, serialize_pipe_string.c_str(), serialize_pipe_string.size() + 1); } catch (const std::exception& e) { context->capture_error(e.what()); diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 55e94faed..945536c03 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -144,9 +144,7 @@ void PipelineSerializer::serialize_operators(std::vectorset_name(pipe_op->operator_name); op->set_module_name(pipe_op->module_name); - // Add support to add each argument in the operator serialize_pipeop_arguments(pipe_op->get_arguments(), op); - // serialize_pipeop_inputs_and_outputs(pipe_op->get_inputs(), pipe_op->get_outputs()); if (pipe_op->module_name == "reader") continue; // Readers do not have tensor outputs, hence return From 64697e6ccb20b6938ee2706ddcb9e7fe8b4feac6 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 9 Oct 2025 05:35:26 -0500 Subject: [PATCH 042/118] Support to serialize to file --- rocAL/include/pipeline/pipeline_serializer.h | 6 ++++++ rocAL/source/pipeline/pipeline_serializer.cpp | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h index 511e268fb..4912a1bc4 100644 --- a/rocAL/include/pipeline/pipeline_serializer.h +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -40,6 +40,12 @@ class PipelineSerializer { ~PipelineSerializer() {} // Serialization methods + /** + * @brief Serialize the current PipelineDef into a file on disk. + * @param file_path Path to save the serialized pipeline (binary payload) + */ + void serialize_to_file(const std::string& file_path); + /** * @brief Serialize the current PipelineDef into a binary string. * @param serialized_string Output string containing the serialized pipeline diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 945536c03..9f5fddf03 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -22,10 +22,22 @@ THE SOFTWARE. #include "pipeline/pipeline_serializer.h" +#include + void PipelineSerializer::serialize_to_string(std::string& serialized_string) { serialized_string = _pipeline.SerializeAsString(); } +void PipelineSerializer::serialize_to_file(const std::string& file_path) { + std::ofstream ofs(file_path, std::ios::binary); + if (!ofs) { + THROW("Failed to open file for writing serialized pipeline: " + file_path); + } + if (!_pipeline.SerializeToOstream(&ofs)) { + THROW("Failed to serialize pipeline to file: " + file_path); + } +} + void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth) { _pipeline.set_num_threads(num_threads); _pipeline.set_batch_size(batch_size); From ffdee4b7b3bfd6d87c98a76a46fbe5a873bd71d7 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 9 Oct 2025 05:37:43 -0500 Subject: [PATCH 043/118] Update CMakeLists version for rocAL --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cab0e2b7..cd5000088 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ elseif(NOT DEFINED CMAKE_CXX_COMPILER AND NOT EXISTS "${ROCM_PATH}/bin/amdclang+ endif() # rocAL Version -set(VERSION "2.4.0") +set(VERSION "2.5.0") # Set Project Version and Language project(rocal VERSION ${VERSION} LANGUAGES CXX) From df3f598af9bc3f2f5042aeef585df76c8d27f581 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 16 Oct 2025 07:18:49 -0500 Subject: [PATCH 044/118] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71cb8199d..7477e2a5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro ### Added * Introduce enum registry to register all the enums present in rocAL. +* Introduce Argument class which stores the value and type of each argument in the Node. +* Support to store the arguments in the Node class. ### Changes * OpenCL backend support - deprecated From 3077acbd68dea55035c433cb16f2b54002233698 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 16 Oct 2025 07:23:55 -0500 Subject: [PATCH 045/118] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7477e2a5e..d0c7151ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,14 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro * Introduce enum registry to register all the enums present in rocAL. * Introduce Argument class which stores the value and type of each argument in the Node. * Support to store the arguments in the Node class. +* Introduces PipelineOperator class to represent operators in the pipeline with metadata. ### Changes * OpenCL backend support - deprecated * CXX Compiler: AMDClang++ - Use compiler core location `${ROCM_PATH}/lib/llvm/bin` * Refactor external enum usage in rocAL, to maintain separation between external and internal enums. * Introduced the following enums ResizeScalingMode, ResizeInterpolationType, MelScaleFormula, AudioBorderType, OutOfBoundsPolicy in commons.h. +* Adds support to track operators in MasterGraph with unique naming. ## rocAL 2.4.0 for ROCm 7.1.0 From d2ccaab6a991ea3e0c9c9f106934fb81490057c7 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 16 Oct 2025 07:43:48 -0500 Subject: [PATCH 046/118] Minor change --- rocAL/include/pipeline/argument_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/argument_types.h b/rocAL/include/pipeline/argument_types.h index 218afb6f7..c56775089 100644 --- a/rocAL/include/pipeline/argument_types.h +++ b/rocAL/include/pipeline/argument_types.h @@ -29,7 +29,7 @@ THE SOFTWARE. #include #include "parameters/parameter_factory.h" -// Enhanced type traits for argument processing (C++17 compatible) +// Enhanced type traits, to check for the type of argument used for argument processing (C++17 compatible) // Vector type detection template From 59f7c0ea86f31b96b8a18c14a130f8d989ff2e24 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 06:09:18 -0500 Subject: [PATCH 047/118] Minor changes --- rocAL/include/pipeline/master_graph.h | 2 +- rocAL/include/pipeline/node.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 0f2970fd8..416065505 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -290,7 +290,7 @@ inline std::shared_ptr MasterGraph::add_node(const std::vector< node->set_graph_id(_loaders_count++); _root_nodes.push_back(node); - // Add each opertor to the pipeline operators list + // Add each operator to the pipeline operators list _pipeline_operators.push_back(std::make_shared(node->node_name() + "_" + std::to_string(_op_idx++), "loader", node)); for (auto &output : outputs) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 1865f4ec0..ec198b42b 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -23,6 +23,8 @@ THE SOFTWARE. #pragma once #include #include +#include +#include #include "pipeline/graph.h" #include "meta_data/meta_data_graph.h" @@ -49,7 +51,7 @@ class Node { const Roi2DCords *get_dst_roi() { return _outputs[0]->info().roi().get_2D_roi(); } void set_graph_id(int id) { _graph_id = id; } int get_graph_id() { return _graph_id; } - virtual std::string node_name() { return ""; } + virtual std::string node_name() const { return ""; } std::vector get_args_list() { return _args; } protected: From 37fe4bef39c78560f4402f6f46f75bcfd767d8ea Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Wed, 22 Oct 2025 17:09:00 +0530 Subject: [PATCH 048/118] Update CHANGELOG.md Co-authored-by: spolifroni-amd --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7477e2a5e..698f7328f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/projects/rocAL/](https://rocm.docs.amd.com/projects/rocAL/en/latest/). -## rocAL 2.5.0 (Unreleased) +## (Unreleased) rocAL 2.5.0 ### Added * Introduce enum registry to register all the enums present in rocAL. From 29359b7bbd0b7d1f359eab1260aacb94c12881fb Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 06:43:57 -0500 Subject: [PATCH 049/118] Add const qualifier --- .../include/augmentations/color_augmentations/node_brightness.h | 2 +- rocAL/include/loaders/image/node_image_loader.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/augmentations/color_augmentations/node_brightness.h b/rocAL/include/augmentations/color_augmentations/node_brightness.h index 9e181ee81..d00e8e32e 100644 --- a/rocAL/include/augmentations/color_augmentations/node_brightness.h +++ b/rocAL/include/augmentations/color_augmentations/node_brightness.h @@ -33,7 +33,7 @@ class BrightnessNode : public Node { void init(float alpha, float beta); void init(FloatParam *alpha_param, FloatParam *beta_param); - std::string node_name() override { return "BrightnessNode"; } + std::string node_name() const override { return "BrightnessNode"; } protected: void create_node() override; diff --git a/rocAL/include/loaders/image/node_image_loader.h b/rocAL/include/loaders/image/node_image_loader.h index 48c46757e..bb307b258 100644 --- a/rocAL/include/loaders/image/node_image_loader.h +++ b/rocAL/include/loaders/image/node_image_loader.h @@ -44,7 +44,7 @@ class ImageLoaderNode : public Node { const char *prefix = "", unsigned sequence_length = 0, unsigned step = 0, unsigned stride = 0, ExternalSourceFileMode external_file_mode = ExternalSourceFileMode::NONE, const std::string &index_path = ""); std::shared_ptr get_loader_module(); - std::string node_name() override { return "ImageLoaderNode"; } + std::string node_name() const override { return "ImageLoaderNode"; } protected: void create_node() override{}; From a6d271e7d1b049cba9cf1a3c579321e4f549e681 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 06:50:39 -0500 Subject: [PATCH 050/118] Add const correctness to get args list --- rocAL/include/pipeline/node.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 62c679244..437327f13 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -52,7 +52,7 @@ class Node { void set_graph_id(int id) { _graph_id = id; } int get_graph_id() { return _graph_id; } virtual std::string node_name() const { return ""; } - std::vector get_args_list() { return _args; } + const std::vector& get_args_list() const { return _args; } protected: virtual void create_node() = 0; From 6bf8527d0dfeab0bf687f238246441dbdff2e744 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 06:51:41 -0500 Subject: [PATCH 051/118] Add const correctness to get args list --- rocAL/include/pipeline/node.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index ec198b42b..2531843e6 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -52,7 +52,7 @@ class Node { void set_graph_id(int id) { _graph_id = id; } int get_graph_id() { return _graph_id; } virtual std::string node_name() const { return ""; } - std::vector get_args_list() { return _args; } + const std::vector& get_args_list() const { return _args; } protected: virtual void create_node() = 0; From cf1227a6f9118ad401434bf63a49ebd522747116 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 06:55:09 -0500 Subject: [PATCH 052/118] Minor change --- rocAL/include/pipeline/pipeline_operator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index 6b4b79df9..105cd06f3 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -37,7 +37,7 @@ class PipelineOperator { } // Set the list of arguments associated with this operator - void set_arguments(std::vector op_arguments) { + void set_arguments(std::vector& op_arguments) { arguments = op_arguments; } From d9ce6c909f7ad4c48dd270bc5126ce37481d74e1 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 06:55:59 -0500 Subject: [PATCH 053/118] Add const correctness to get args list --- rocAL/include/pipeline/node.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 2234a0128..d450758f3 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -49,7 +49,7 @@ class Node { const Roi2DCords *get_dst_roi() { return _outputs[0]->info().roi().get_2D_roi(); } void set_graph_id(int id) { _graph_id = id; } int get_graph_id() { return _graph_id; } - std::vector get_args_list() { return _args; } + const std::vector& get_args_list() const { return _args; } protected: virtual void create_node() = 0; From 9cfb80f1ba65de2f76baf177f9b2e8a6b197a618 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 10:13:10 -0500 Subject: [PATCH 054/118] Minor change --- rocAL/include/pipeline/pipeline_serializer.h | 6 +++--- rocAL/source/pipeline/pipeline_serializer.cpp | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h index 4912a1bc4..403d1cdb4 100644 --- a/rocAL/include/pipeline/pipeline_serializer.h +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -29,7 +29,7 @@ THE SOFTWARE. #include "rocal.pb.h" /** - * @brief Helper to serialize a built rocAL pipeline into a protobuf-based payload. + * @brief Helper to serialize a built rocAL pipeline into protobuffers. * * This class gathers top-level pipeline configuration, operators (names, modules, * arguments) and tensors (inputs/outputs) and writes them into rocal_proto::PipelineDef. @@ -61,7 +61,7 @@ class PipelineSerializer { */ void serialize_output_tensors(TensorList& output_tensors_list); /** - * @brief Serialize all operators, their arguments, and IO tensors. + * @brief Serialize all operators in the pipeline, their arguments, and IO tensors. */ void serialize_operators(std::vector>& operators); /** @@ -70,6 +70,6 @@ class PipelineSerializer { void serialize_pipeop_arguments(const std::vector& arguments_list, rocal_proto::OperatorDef *opdef); protected: - rocal_proto::PipelineDef _pipeline; + rocal_proto::PipelineDef _pipeline_proto; }; diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 9f5fddf03..6255e8579 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -25,7 +25,7 @@ THE SOFTWARE. #include void PipelineSerializer::serialize_to_string(std::string& serialized_string) { - serialized_string = _pipeline.SerializeAsString(); + serialized_string = _pipeline_proto.SerializeAsString(); } void PipelineSerializer::serialize_to_file(const std::string& file_path) { @@ -33,17 +33,17 @@ void PipelineSerializer::serialize_to_file(const std::string& file_path) { if (!ofs) { THROW("Failed to open file for writing serialized pipeline: " + file_path); } - if (!_pipeline.SerializeToOstream(&ofs)) { + if (!_pipeline_proto.SerializeToOstream(&ofs)) { THROW("Failed to serialize pipeline to file: " + file_path); } } void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth) { - _pipeline.set_num_threads(num_threads); - _pipeline.set_batch_size(batch_size); - _pipeline.set_device_id(device_id); - _pipeline.set_rocal_cpu(device_type == RocalMemType::HOST ? true : false); - _pipeline.set_prefetch_queue_depth(prefetch_queue_depth); + _pipeline_proto.set_num_threads(num_threads); + _pipeline_proto.set_batch_size(batch_size); + _pipeline_proto.set_device_id(device_id); + _pipeline_proto.set_rocal_cpu(device_type == RocalMemType::HOST ? true : false); + _pipeline_proto.set_prefetch_queue_depth(prefetch_queue_depth); } void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input = false) { @@ -153,7 +153,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& void PipelineSerializer::serialize_operators(std::vector>& operators) { // Serialize all operators for (auto &pipe_op : operators) { - rocal_proto::OperatorDef *op = _pipeline.add_operators(); + rocal_proto::OperatorDef *op = _pipeline_proto.add_operators(); op->set_name(pipe_op->operator_name); op->set_module_name(pipe_op->module_name); serialize_pipeop_arguments(pipe_op->get_arguments(), op); @@ -179,7 +179,7 @@ void PipelineSerializer::serialize_output_tensors(TensorList& output_tensors_lis // Serialize the pipeline outputs for (size_t idx = 0; idx < output_tensors_list.size(); idx++) { - rocal_proto::InputOutput *output = _pipeline.add_pipe_outputs(); + rocal_proto::InputOutput *output = _pipeline_proto.add_pipe_outputs(); auto pipe_output = output_tensors_list[idx]; set_tensor_proto(output, pipe_output, false); } From 09f493e6debd164b9b997f62944f58c9ed98cddf Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 22 Oct 2025 10:21:47 -0500 Subject: [PATCH 055/118] Return serialized string reference from MasterGraph --- rocAL/include/pipeline/master_graph.h | 2 +- rocAL/source/api/rocal_api.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 3bbfb4495..dd5f9a61e 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -157,7 +157,7 @@ class MasterGraph { * Serialize API */ void serialize(size_t &serialized_string_size); // Serialize the current pipeline to an internal string and return its size. - std::string get_serialized_string() { return _serialized_pipeline; } + std::string& get_serialized_string() { return _serialized_pipeline; } private: Status update_node_parameters(); void create_single_graph(); diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index 41b797356..8fbe748a3 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -127,7 +127,7 @@ rocalGetSerializedString(RocalContext rocal_context, char* serialized_string) { THROW("String copy failed, Invalid pointer passed for serialize") } - auto serialize_pipe_string = context->master_graph->get_serialized_string(); + auto& serialize_pipe_string = context->master_graph->get_serialized_string(); if (serialize_pipe_string.empty()) THROW("Serialized string is empty, Invoke rocalSerialize before obtaining the string") std::memcpy(serialized_string, serialize_pipe_string.c_str(), serialize_pipe_string.size() + 1); From 57d219c3ac51d88ed1235d935293c2d69051b286 Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Thu, 23 Oct 2025 16:17:50 +0530 Subject: [PATCH 056/118] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/proto/rocal.proto | 2 +- rocAL/source/api/rocal_api.cpp | 2 +- rocAL/source/pipeline/pipeline_serializer.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index 319dd6d51..3bc3d51ab 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -24,7 +24,7 @@ syntax = "proto3"; package rocal_proto; -// Stores the Input/Ouptut tensors +// Stores the Input/Output tensors message InputOutput { string name = 1; optional string type = 2; diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index 8fbe748a3..2d195d29c 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -134,7 +134,7 @@ rocalGetSerializedString(RocalContext rocal_context, char* serialized_string) { } catch (const std::exception& e) { context->capture_error(e.what()); - ERR(e.what()) + ERR(e.what()); return ROCAL_RUNTIME_ERROR; } return ROCAL_OK; diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 6255e8579..cd56b5784 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -126,7 +126,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& } else { // Scalar path (use flat repeated fields) if (op_arg.values.size() > 1) { - ERR("Argument has more than one value, is_vector should be set to true") + ERR("Argument has more than one value, is_vector should be set to true"); } for (auto &v : op_arg.values) { if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr") { From 4b16eec14a54e4ceaf9f8bc4fcaeb5f84b0ecc1b Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 23 Oct 2025 06:19:20 -0500 Subject: [PATCH 057/118] Obtain serialized string size as ptr --- rocAL/include/api/rocal_api.h | 2 +- rocAL/include/pipeline/master_graph.h | 2 +- rocAL/source/api/rocal_api.cpp | 2 +- rocAL/source/pipeline/master_graph.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rocAL/include/api/rocal_api.h b/rocAL/include/api/rocal_api.h index 1e322f174..7a4b03323 100644 --- a/rocAL/include/api/rocal_api.h +++ b/rocAL/include/api/rocal_api.h @@ -116,7 +116,7 @@ extern "C" RocalStatus ROCAL_API_CALL rocalRelease(RocalContext rocal_context); * \param [out] serialized_string_size number of bytes in the serialized string * \return A \ref RocalStatus - A status code indicating the success or failure. */ -extern "C" RocalStatus ROCAL_API_CALL rocalSerialize(RocalContext rocal_context, size_t &serialized_string_size); +extern "C" RocalStatus ROCAL_API_CALL rocalSerialize(RocalContext rocal_context, size_t* serialized_string_size); /*! * \brief Copy the last serialized pipeline string into a user buffer. diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index dd5f9a61e..d298d3040 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -156,7 +156,7 @@ class MasterGraph { /** * Serialize API */ - void serialize(size_t &serialized_string_size); // Serialize the current pipeline to an internal string and return its size. + void serialize(size_t *serialized_string_size); // Serialize the current pipeline to an internal string and return its size. std::string& get_serialized_string() { return _serialized_pipeline; } private: Status update_node_parameters(); diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index 8fbe748a3..3cfd78769 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -107,7 +107,7 @@ rocalVerify(RocalContext p_context) { } RocalStatus ROCAL_API_CALL -rocalSerialize(RocalContext rocal_context, size_t &serialized_string_size) { +rocalSerialize(RocalContext rocal_context, size_t *serialized_string_size) { auto context = static_cast(rocal_context); try { context->master_graph->serialize(serialized_string_size); diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 3fe4220b3..7f1a824cf 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1772,10 +1772,10 @@ void MasterGraph::feed_external_input(const std::vector& input_imag } } -void MasterGraph::serialize(size_t &serialized_string_size) { +void MasterGraph::serialize(size_t *serialized_string_size) { _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth); _pipeline_serializer.serialize_operators(_pipeline_operators); _pipeline_serializer.serialize_output_tensors(_internal_tensor_list); _pipeline_serializer.serialize_to_string(_serialized_pipeline); - serialized_string_size = _serialized_pipeline.size(); + *serialized_string_size = _serialized_pipeline.size(); } From 6d6a6b6fde883f341b49604a2cf60af7a136eade Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 23 Oct 2025 06:21:30 -0500 Subject: [PATCH 058/118] Minor change --- rocAL/source/pipeline/pipeline_serializer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 6255e8579..78ccef4c6 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -72,6 +72,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& arg->set_instance_name(op_arg.sub_type_name); if (op_arg.is_parameter) { + THROW("Parameter types are unsupported for Argument " + op_arg.arg_name); // TODO - Will be enabled later // rocal_proto::Parameter *param = arg->mutable_param(); // serialize_parameter_to_protobuf(param, op_arg); From 2b1bf5defb7b3d4ad9175781df7256a6adc873dc Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 23 Oct 2025 08:21:43 -0500 Subject: [PATCH 059/118] Add reset for pipeline serializer --- rocAL/include/pipeline/pipeline_serializer.h | 5 +++++ rocAL/source/pipeline/master_graph.cpp | 1 + rocAL/source/pipeline/pipeline_serializer.cpp | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h index 403d1cdb4..57d2cf521 100644 --- a/rocAL/include/pipeline/pipeline_serializer.h +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -69,6 +69,11 @@ class PipelineSerializer { */ void serialize_pipeop_arguments(const std::vector& arguments_list, rocal_proto::OperatorDef *opdef); + /** + * @brief Clear any previously serialized state to start fresh. + */ + void reset(); + protected: rocal_proto::PipelineDef _pipeline_proto; diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 7f1a824cf..9ef6d5e8e 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1773,6 +1773,7 @@ void MasterGraph::feed_external_input(const std::vector& input_imag } void MasterGraph::serialize(size_t *serialized_string_size) { + _pipeline_serializer.reset(); _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth); _pipeline_serializer.serialize_operators(_pipeline_operators); _pipeline_serializer.serialize_output_tensors(_internal_tensor_list); diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 78ccef4c6..89640b92c 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -185,3 +185,7 @@ void PipelineSerializer::serialize_output_tensors(TensorList& output_tensors_lis set_tensor_proto(output, pipe_output, false); } } + +void PipelineSerializer::reset() { + _pipeline_proto.Clear(); +} From a62ed11d3bd9f104604256a6a0445af229fe5f72 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 23 Oct 2025 08:56:23 -0500 Subject: [PATCH 060/118] Add cstring include --- rocAL/source/api/rocal_api.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index 3cfd78769..f22d5de9a 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -24,6 +24,7 @@ THE SOFTWARE. #include #include +#include #include "pipeline/commons.h" #include "pipeline/context.h" From 3f245d2116f1baaa8e81006ea85a233b3862ec6d Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Fri, 24 Oct 2025 04:28:51 -0500 Subject: [PATCH 061/118] Minor change --- rocAL/source/pipeline/pipeline_serializer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index b8ec7a9dc..3b4885bda 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -46,7 +46,7 @@ void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t ba _pipeline_proto.set_prefetch_queue_depth(prefetch_queue_depth); } -void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input = false) { +void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input) { in_out_proto->set_name(tensor->tensor_name()); in_out_proto->set_device(static_cast(tensor->info().mem_type())); in_out_proto->set_dtype(static_cast(tensor->info().data_type())); @@ -171,7 +171,7 @@ void PipelineSerializer::serialize_operators(std::vectorget_outputs()) { rocal_proto::InputOutput *output = op->add_outputs(); - set_tensor_proto(output, node_output); + set_tensor_proto(output, node_output, false); } } } From d9226ccc5834ebe0450eca9c937c9dbfc5e181ea Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Fri, 24 Oct 2025 09:41:17 -0500 Subject: [PATCH 062/118] Update CHANGELOG --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8db4da4d7..fcf152217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,10 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro ## (Unreleased) rocAL 2.5.0 ### Added -* Introduce enum registry to register all the enums present in rocAL. -* Introduce Argument class which stores the value and type of each argument in the Node. +* `EnumRegistry` to register all the enums present in rocAL. +* `Argument` class which stores the value and type of each argument in the Node. * Support to store the arguments in the Node class. -* Introduces PipelineOperator class to represent operators in the pipeline with metadata. +* `PipelineOperator` class to represent operators in the pipeline with metadata. ### Changes * OpenCL backend support - deprecated From 7084be1ec24639cf01e107e8820044e026e53134 Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Mon, 27 Oct 2025 12:44:39 +0530 Subject: [PATCH 063/118] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/include/pipeline/pipeline_operator.h | 4 ++-- rocAL/source/api/rocal_api.cpp | 2 +- rocAL/source/pipeline/pipeline_serializer.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index 38232896f..f8ce5da66 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -37,8 +37,8 @@ class PipelineOperator { } // Set the list of arguments associated with this operator - void set_arguments(const std::vector& op_arguments) { - arguments = op_arguments; + void set_arguments(const std::vector& arguments) { + this->arguments = arguments; } /** diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index 10386247e..ac402e6ed 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -130,7 +130,7 @@ rocalGetSerializedString(RocalContext rocal_context, char* serialized_string) { auto& serialize_pipe_string = context->master_graph->get_serialized_string(); if (serialize_pipe_string.empty()) - THROW("Serialized string is empty, Invoke rocalSerialize before obtaining the string") + THROW("Serialized string is empty, invoke rocalSerialize before obtaining the string.") std::memcpy(serialized_string, serialize_pipe_string.c_str(), serialize_pipe_string.size() + 1); } catch (const std::exception& e) { diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 3b4885bda..0f0f1b484 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -127,7 +127,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& } else { // Scalar path (use flat repeated fields) if (op_arg.values.size() > 1) { - ERR("Argument has more than one value, is_vector should be set to true"); + THROW("Argument '" + op_arg.arg_name + "' has more than one value, but is_vector is false. This is not allowed."); } for (auto &v : op_arg.values) { if (op_arg.type_name == "int" || op_arg.type_name == "shared_ptr") { From 9a3bee66b5bcbbea9882eb90a48a1f5effeaeded Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 00:33:39 -0500 Subject: [PATCH 064/118] Minor changes --- rocAL/include/pipeline/pipeline_operator.h | 4 ++-- rocAL/proto/rocal.proto | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index f8ce5da66..160f4bf10 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -58,14 +58,14 @@ class PipelineOperator { /** * Get the input tensors connected to the underlying node. */ - const std::vector& get_inputs() { + const std::vector& get_inputs() const { return this->node->input(); } /** * Get the output tensors produced by the underlying node. */ - const std::vector& get_outputs() { + const std::vector& get_outputs() const { return this->node->output(); } diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index 3bc3d51ab..eb6431f25 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -76,8 +76,8 @@ message Arguments { optional Parameter param = 9; optional EnumType enum_value = 10; - // vector storage (deprecated): use *_vectors below instead - bool is_vector = 11 [deprecated = true]; + // vector storage + bool is_vector = 11; // Vector payloads (use these when the argument carries vectors) repeated FloatVector float_vectors = 12; From 9fb38a1e77b88735f60b4e946cf0704e18e94a6e Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 00:56:58 -0500 Subject: [PATCH 065/118] Add empty lines in between functions --- rocAL/include/parameters/parameter_random.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rocAL/include/parameters/parameter_random.h b/rocAL/include/parameters/parameter_random.h index 61d729c25..93d2b293b 100644 --- a/rocAL/include/parameters/parameter_random.h +++ b/rocAL/include/parameters/parameter_random.h @@ -104,6 +104,7 @@ class UniformRand : public Parameter { bool single_value() const override { return (_start == _end); } + std::pair get_start_and_end() { return std::make_pair(_start, _end); } @@ -228,8 +229,11 @@ struct CustomRand : public Parameter { bool single_value() const override { return (_values.size() == 1); } + std::vector& get_values() { return _values; } + std::vector& get_frequencies() { return _frequencies; } + unsigned size() { return _size; } private: From c621cce2d267fd132fcec928401bcdc1070756be Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 01:00:32 -0500 Subject: [PATCH 066/118] Remove Params proto --- rocAL/proto/rocal.proto | 9 --------- 1 file changed, 9 deletions(-) diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index eb6431f25..64ed6c7e6 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -37,14 +37,6 @@ message InputOutput { uint32 num_dims = 9; } -message Parameter { - int32 param_type = 1; - repeated float param_val_float = 2; - repeated int32 param_val_int = 3; - repeated double frequency = 4; // Used only for CustomRand param - optional uint32 size = 5; // Used only for CustomRand param -} - message EnumType { string name = 1; int32 value = 2; @@ -73,7 +65,6 @@ message Arguments { repeated string strings = 6; repeated bool bools = 7; repeated uint64 uints = 8; - optional Parameter param = 9; optional EnumType enum_value = 10; // vector storage From 6207d4a32140580424939508232b949b22754e4f Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 01:01:50 -0500 Subject: [PATCH 067/118] Add params proto --- rocAL/proto/rocal.proto | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index 64ed6c7e6..eb6431f25 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -37,6 +37,14 @@ message InputOutput { uint32 num_dims = 9; } +message Parameter { + int32 param_type = 1; + repeated float param_val_float = 2; + repeated int32 param_val_int = 3; + repeated double frequency = 4; // Used only for CustomRand param + optional uint32 size = 5; // Used only for CustomRand param +} + message EnumType { string name = 1; int32 value = 2; @@ -65,6 +73,7 @@ message Arguments { repeated string strings = 6; repeated bool bools = 7; repeated uint64 uints = 8; + optional Parameter param = 9; optional EnumType enum_value = 10; // vector storage From 85a7ea815bcfda8e9e59310a95dbac34c9d398d1 Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Tue, 28 Oct 2025 11:38:10 +0530 Subject: [PATCH 068/118] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/include/parameters/parameter_random.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rocAL/include/parameters/parameter_random.h b/rocAL/include/parameters/parameter_random.h index 93d2b293b..2c3e2ad31 100644 --- a/rocAL/include/parameters/parameter_random.h +++ b/rocAL/include/parameters/parameter_random.h @@ -105,7 +105,7 @@ class UniformRand : public Parameter { return (_start == _end); } - std::pair get_start_and_end() { + std::pair get_start_and_end() { return std::make_pair(_start, _end); } @@ -230,9 +230,9 @@ struct CustomRand : public Parameter { return (_values.size() == 1); } - std::vector& get_values() { return _values; } + const std::vector& get_values() const { return _values; } - std::vector& get_frequencies() { return _frequencies; } + const std::vector& get_frequencies() const { return _frequencies; } unsigned size() { return _size; } From ab2d044aca438154d5130d1e77e2e270854b1504 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 01:40:40 -0500 Subject: [PATCH 069/118] Minor changes --- rocAL/include/parameters/parameter_random.h | 2 +- rocAL/proto/rocal.proto | 9 ++++----- rocAL/source/pipeline/pipeline_serializer.cpp | 2 ++ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/rocAL/include/parameters/parameter_random.h b/rocAL/include/parameters/parameter_random.h index 2c3e2ad31..0491e7198 100644 --- a/rocAL/include/parameters/parameter_random.h +++ b/rocAL/include/parameters/parameter_random.h @@ -245,5 +245,5 @@ struct CustomRand : public Parameter { std::vector _param_values; //!< The values will be used in parameter_vx.h file after renewing std::mt19937 _generator; std::mutex _lock; - unsigned _size; + unsigned _size = 0; }; \ No newline at end of file diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index eb6431f25..eef0a238a 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -38,11 +38,10 @@ message InputOutput { } message Parameter { - int32 param_type = 1; - repeated float param_val_float = 2; - repeated int32 param_val_int = 3; - repeated double frequency = 4; // Used only for CustomRand param - optional uint32 size = 5; // Used only for CustomRand param + repeated float param_val_float = 1; + repeated int32 param_val_int = 2; + repeated double frequency = 3; // Used only for CustomRand param + optional uint32 size = 4; // Used only for CustomRand param } message EnumType { diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 3943a3c5a..2ea77884f 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -77,6 +77,8 @@ auto extract_param_core(const Argument &op_arg) { } else if constexpr (std::is_same_v) { auto param = std::get(op_arg.param); return param->core; + } else { + THROW("Extract_param_core only supports int and float types.") } } From 8565cfd83d20db8a15426a43afe3f1c0ecb09656 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 02:29:13 -0500 Subject: [PATCH 070/118] Fix serialize test --- tests/cpp_api/serialization_test/serialization_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index b2a3ca968..1fa650f4c 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -113,7 +113,7 @@ int main(int argc, const char **argv) { // Get the size of the serialized string size_t serialized_string_size = 0; - RocalStatus serialize_status = rocalSerialize(handle, serialized_string_size); + RocalStatus serialize_status = rocalSerialize(handle, &serialized_string_size); if (serialize_status != ROCAL_OK) { std::cout << "Failed to serialize pipeline: " << rocalGetErrorMessage(handle) << std::endl; @@ -123,11 +123,11 @@ int main(int argc, const char **argv) { std::cout << "Serialized string size: " << serialized_string_size << " bytes" << std::endl; - // Allocate buffer for the serialized string + // Allocate buffer for the serialized string std::string serialized_pipe_string(serialized_string_size, '\0'); // Get the actual serialized string - RocalStatus get_string_status = rocalGetSerializedString(handle, serialized_pipe_string.c_str()); + RocalStatus get_string_status = rocalGetSerializedString(handle, serialized_pipe_string.data()); if (get_string_status != ROCAL_OK) { std::cout << "Failed to get serialized string: " << rocalGetErrorMessage(handle) << std::endl; From 651e48ef998ccf6eb035235343984341773094eb Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 02:31:22 -0500 Subject: [PATCH 071/118] Add CMakeLists for serialization tests --- tests/cpp_api/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cpp_api/CMakeLists.txt b/tests/cpp_api/CMakeLists.txt index 13a69ea24..e1c1da436 100644 --- a/tests/cpp_api/CMakeLists.txt +++ b/tests/cpp_api/CMakeLists.txt @@ -251,3 +251,15 @@ if(rocjpeg_FOUND) ${ROCM_PATH}/share/rocal/test/data/images/AMD-tinyDataSet ${ROCM_PATH}/share/rocal/test/data/images/AMD-tinyDataSet-val.txt 1 1 224 224 1 1 2 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/basic_test) endif() + +# 17 - serialization_test_cpu +add_test(NAME serialization_test_cpu + COMMAND serialization_test + ${ROCM_PATH}/share/rocal/test/data/images/AMD-tinyDataSet 0 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/serialization_test) + +# 18 - serialization_test_gpu +add_test(NAME serialization_test_gpu + COMMAND serialization_test + ${ROCM_PATH}/share/rocal/test/data/images/AMD-tinyDataSet 1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/serialization_test) From 5275fbf3818166168c82eed71de962ee3a492e06 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 02:35:20 -0500 Subject: [PATCH 072/118] Use random brightness API --- tests/cpp_api/serialization_test/serialization_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 1fa650f4c..0f2c355f9 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -90,7 +90,7 @@ int main(int argc, const char **argv) { } // Add brightness augmentation (mark as output) - RocalTensor brightness_output = rocalBrightnessFixed(handle, decoded_output, 0.5, 1.5, true); + RocalTensor brightness_output = rocalBrightness(handle, decoded_output, true); if (rocalGetStatus(handle) != ROCAL_OK) { std::cout << "Brightness augmentation could not initialize : " << rocalGetErrorMessage(handle) << std::endl; From 70ab49967b26a9084821ba472de9fc3bcc739a2e Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 28 Oct 2025 02:50:04 -0500 Subject: [PATCH 073/118] Add support to build serialization tests in CMakeLists --- tests/cpp_api/CMakeLists.txt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/cpp_api/CMakeLists.txt b/tests/cpp_api/CMakeLists.txt index e1c1da436..da87b6d7c 100644 --- a/tests/cpp_api/CMakeLists.txt +++ b/tests/cpp_api/CMakeLists.txt @@ -253,11 +253,17 @@ if(rocjpeg_FOUND) endif() # 17 - serialization_test_cpu -add_test(NAME serialization_test_cpu - COMMAND serialization_test - ${ROCM_PATH}/share/rocal/test/data/images/AMD-tinyDataSet 0 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/serialization_test) - +add_test( + NAME + serialization_test_cpu + COMMAND + "${CMAKE_CTEST_COMMAND}" + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/serialization_test" + "${CMAKE_CURRENT_BINARY_DIR}/serialization_test" + --build-generator "${CMAKE_GENERATOR}" + --test-command "serialization_test" + ${ROCM_PATH}/share/rocal/test/data/images/AMD-tinyDataSet 0 +) # 18 - serialization_test_gpu add_test(NAME serialization_test_gpu COMMAND serialization_test From fd54bd3f638603eae6decf39c72e9e8d7a1e78eb Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 5 Nov 2025 08:14:33 -0600 Subject: [PATCH 074/118] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcf152217..5c4d30b5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro * `Argument` class which stores the value and type of each argument in the Node. * Support to store the arguments in the Node class. * `PipelineOperator` class to represent operators in the pipeline with metadata. +* `PipelineSerializer` class to implement pipeline serialization functionality in rocAL. ### Changes * OpenCL backend support - deprecated @@ -16,6 +17,8 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro * Refactor external enum usage in rocAL, to maintain separation between external and internal enums. * Introduced the following enums ResizeScalingMode, ResizeInterpolationType, MelScaleFormula, AudioBorderType, OutOfBoundsPolicy in commons.h. * Adds support to track operators in MasterGraph with unique naming. +* Adds new public APIs rocalSerialize() and rocalGetSerializedString() for serializing pipelines. +* Add support to store the pipeline into protobuf format. ## rocAL 2.4.0 for ROCm 7.1.0 From 5695f3c32017f7a0900fe7fd0afa64b1ea894f35 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 5 Nov 2025 08:16:30 -0600 Subject: [PATCH 075/118] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c4d30b5c..affa76296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro * Adds support to track operators in MasterGraph with unique naming. * Adds new public APIs rocalSerialize() and rocalGetSerializedString() for serializing pipelines. * Add support to store the pipeline into protobuf format. +* Adds template-based serialization functions for different parameter types to convert to protobuf format. ## rocAL 2.4.0 for ROCm 7.1.0 From 7cb5620058260c22d142226140cb2fe034c1848d Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 5 Nov 2025 08:17:48 -0600 Subject: [PATCH 076/118] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index affa76296..c18e44eb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro * Support to store the arguments in the Node class. * `PipelineOperator` class to represent operators in the pipeline with metadata. * `PipelineSerializer` class to implement pipeline serialization functionality in rocAL. +* Serialization test to validate pipeline serialization functionality. ### Changes * OpenCL backend support - deprecated From 51046c238390ed50ab26b3dd3eab46d5ed0301fd Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 6 Nov 2025 02:06:16 -0600 Subject: [PATCH 077/118] Change rocal proto file to proto2 features --- rocAL/proto/rocal.proto | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index 64ed6c7e6..5316a7391 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -20,26 +20,26 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -syntax = "proto3"; +syntax = "proto2"; package rocal_proto; // Stores the Input/Output tensors message InputOutput { - string name = 1; + required string name = 1; optional string type = 2; - bool is_argument_input = 3; - int32 device = 4; + required bool is_argument_input = 3; + required int32 device = 4; optional int32 dtype = 5; optional int32 layout = 6; optional int32 color_format = 7; repeated uint64 dims = 8; - uint32 num_dims = 9; + required uint32 num_dims = 9; } message EnumType { - string name = 1; - int32 value = 2; + required string name = 1; + required int32 value = 2; } // Vector containers for Arguments (use these when passing vectors) @@ -57,7 +57,7 @@ message StringVector { // Stores a single argument message Arguments { - string name = 1; + required string name = 1; optional string type = 2; optional string instance_name = 3; repeated float floats = 4; @@ -68,7 +68,7 @@ message Arguments { optional EnumType enum_value = 10; // vector storage - bool is_vector = 11; + optional bool is_vector = 11; // Vector payloads (use these when the argument carries vectors) repeated FloatVector float_vectors = 12; @@ -78,7 +78,7 @@ message Arguments { // Stores info about each operator in pipeline message OperatorDef { - string name = 1; + required string name = 1; optional string module_name = 2; // Arguments repeated Arguments args = 3; @@ -90,7 +90,7 @@ message OperatorDef { // Stores pipeline arguments and a list of nodes/operators message PipelineDef { optional int64 num_threads = 1; - int32 batch_size = 2; + required int32 batch_size = 2; optional int32 device_id = 3; optional int64 seed = 4; optional bool rocal_cpu = 5; From c1ab6979011292ee0f38299117cc97f34c9b006a Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 12 Nov 2025 00:19:03 -0600 Subject: [PATCH 078/118] Generate UID for tensors from MasterGraph --- rocAL/include/pipeline/master_graph.h | 2 ++ rocAL/include/pipeline/tensor.h | 5 +-- rocAL/source/pipeline/master_graph.cpp | 46 +++++++++++++------------- rocAL/source/pipeline/tensor.cpp | 8 ++++- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 416065505..2367cfe28 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -168,6 +168,7 @@ class MasterGraph { bool no_more_processed_data(); // is_out_of_data() is called to check the remaining batch count from each loader module, if any of the loader module has consumed all the batches it returns true. bool is_out_of_data(); + inline std::string get_tensor_uid() { return std::to_string(_tensor_idx++); } RingBuffer _ring_buffer; //!< The queue that keeps the tensors that have benn processed by the internal thread (_output_thread) asynchronous to the user's thread pMetaDataBatch _augmented_meta_data = nullptr; //!< The output of the meta_data_graph, std::shared_ptr _random_bbox_crop_cords_data = nullptr; @@ -239,6 +240,7 @@ class MasterGraph { TimingDbg _rb_block_if_empty_time, _rb_block_if_full_time; std::vector> _pipeline_operators; // Contains the info of all the operators present in the pipeline int _op_idx = 0; // Operator index used to uniquely name PipelineOperator entries + int _tensor_idx = 0; // Index/counter used to uniquely name Tensor instances created in the pipeline }; template diff --git a/rocAL/include/pipeline/tensor.h b/rocAL/include/pipeline/tensor.h index ede9e51fa..eee5e7ac9 100644 --- a/rocAL/include/pipeline/tensor.h +++ b/rocAL/include/pipeline/tensor.h @@ -342,6 +342,8 @@ class Tensor : public rocalTensor { //! Constructor accepting the tensor information as input explicit Tensor(const TensorInfo& tensor_info); + //! Constructor accepting the tensor information and a name + explicit Tensor(const TensorInfo& tensor_info, const std::string& name); int create(vx_context context); void create_roi_tensor_from_handle(void** handle); void update_tensor_roi(const std::vector& width, const std::vector& height); @@ -382,7 +384,6 @@ class Tensor : public rocalTensor { TensorInfo _info; //!< The structure holding the info related to the stored OpenVX tensor vx_context _context = nullptr; vx_tensor _vx_roi_handle = nullptr; //!< The OpenVX tensor for ROI - inline static int _tensor_idx = 0; // Tensor index used to uniquely name Tensors std::string _tensor_name; }; @@ -406,7 +407,7 @@ class TensorList : public rocalTensorList { Tensor* at(size_t index) override { return _tensor_list[index]; } void operator=(TensorList& other) { for (unsigned idx = 0; idx < other.size(); idx++) { - auto* new_tensor = new Tensor(other[idx]->info()); + auto* new_tensor = new Tensor(other[idx]->info(), other[idx]->tensor_name() + "_1"); if (new_tensor->create_from_handle(other[idx]->context()) != 0) THROW("Cannot create the tensor from handle") this->push_back(new_tensor); diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 3565ee62a..64c405de7 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -294,7 +294,7 @@ MasterGraph::create_internal_tensor(const TensorInfo &info) { /* * NOTE: This function creates a regular (non-virtual) tensor */ - auto output = new Tensor(info); + auto output = new Tensor(info, get_tensor_uid()); if (output->create_from_handle(_context) != 0) THROW("Creating output tensor for loader failed"); @@ -305,13 +305,13 @@ MasterGraph::create_internal_tensor(const TensorInfo &info) { Tensor * MasterGraph::create_tensor(const TensorInfo &info, bool is_output) { - auto *output = new Tensor(info); + auto *output = new Tensor(info, get_tensor_uid()); // if the tensor is not an output tensor, the tensor creation is deferred and later it'll be created as a virtual tensor if (is_output) { if (output->create_from_handle(_context) != 0) THROW("Cannot create the tensor from handle") _internal_tensor_list.push_back(output); - _output_tensor_list.push_back(new Tensor(info)); // Creating a replica of the output tensor to be returned to the user + _output_tensor_list.push_back(new Tensor(info, get_tensor_uid())); // Creating a replica of the output tensor to be returned to the user } return output; @@ -323,7 +323,7 @@ void MasterGraph::set_output(Tensor *output_tensor) { THROW("Cannot create the tensor from handle") _internal_tensor_list.push_back(output_tensor); - _output_tensor_list.push_back(new Tensor(output_tensor->info())); // Creating a replica of the output tensor to be returned to the user + _output_tensor_list.push_back(new Tensor(output_tensor->info(), get_tensor_uid())); // Creating a replica of the output tensor to be returned to the user } else { // Decoder case only auto actual_output = create_tensor(output_tensor->info(), true); @@ -1076,15 +1076,15 @@ TensorListVector* MasterGraph::create_coco_meta_data_reader(const char *source_p { auto labels_info = default_labels_info; auto bbox_info = default_bbox_info; - _labels_tensor_list.push_back(new Tensor(labels_info)); - _bbox_tensor_list.push_back(new Tensor(bbox_info)); + _labels_tensor_list.push_back(new Tensor(labels_info, "label_" + get_tensor_uid())); + _bbox_tensor_list.push_back(new Tensor(bbox_info, "bbox_" + get_tensor_uid())); if (metadata_type == MetaDataType::PolygonMask) { auto mask_info = default_mask_info; - _mask_tensor_list.push_back(new Tensor(mask_info)); + _mask_tensor_list.push_back(new Tensor(mask_info, "mask_" + get_tensor_uid())); } if(is_box_iou_matcher) { auto matches_info = default_matches_info; - _matches_tensor_list.push_back(new Tensor(matches_info)); + _matches_tensor_list.push_back(new Tensor(matches_info, "matches_" + get_tensor_uid())); } } _ring_buffer.init_metadata(RocalMemType::HOST, _meta_data_buffer_size); @@ -1117,7 +1117,7 @@ TensorListVector* MasterGraph::create_tf_record_meta_data_reader(const char *sou for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - auto tensor = new Tensor(info); + auto tensor = new Tensor(info, "label_" + get_tensor_uid()); _labels_tensor_list.push_back(tensor); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); @@ -1135,8 +1135,8 @@ TensorListVector* MasterGraph::create_tf_record_meta_data_reader(const char *sou for (unsigned i = 0; i < _user_batch_size; i++) { auto labels_info = default_labels_info; auto bbox_info = default_bbox_info; - _labels_tensor_list.push_back(new Tensor(labels_info)); - _bbox_tensor_list.push_back(new Tensor(bbox_info)); + _labels_tensor_list.push_back(new Tensor(labels_info, "label_" + get_tensor_uid())); + _bbox_tensor_list.push_back(new Tensor(bbox_info, "bbox_" + get_tensor_uid())); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); _metadata_output_tensor_list.emplace_back(&_bbox_tensor_list); @@ -1173,7 +1173,7 @@ TensorListVector* MasterGraph::create_label_reader(const char *source_path, Meta for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - _labels_tensor_list.push_back(new Tensor(info)); + _labels_tensor_list.push_back(new Tensor(info, "label_" + get_tensor_uid())); } _ring_buffer.init_metadata(RocalMemType::HOST, _meta_data_buffer_size); _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); @@ -1209,7 +1209,7 @@ TensorListVector* MasterGraph::create_webdataset_reader( for (unsigned i = 0; i < _user_batch_size; i++) { _meta_data_buffer_size.emplace_back(_user_batch_size * default_ascii_values_info.data_size()); auto info = default_ascii_values_info; - auto tensor = new Tensor(info); + auto tensor = new Tensor(info, "wds_" + get_tensor_uid()); _ascii_tensor_list[ext_count].push_back(tensor); } _metadata_output_tensor_list.emplace_back(&_ascii_tensor_list[ext_count]); @@ -1241,7 +1241,7 @@ TensorListVector* MasterGraph::create_video_label_reader(const char *source_path for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - auto tensor = new Tensor(info); + auto tensor = new Tensor(info, "label_" + get_tensor_uid()); _labels_tensor_list.push_back(tensor); } _ring_buffer.init_metadata(RocalMemType::HOST, _meta_data_buffer_size); @@ -1268,7 +1268,7 @@ TensorListVector* MasterGraph::create_mxnet_label_reader(const char *source_path for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - auto tensor = new Tensor(info); + auto tensor = new Tensor(info, "label_" + get_tensor_uid()); _labels_tensor_list.push_back(tensor); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); @@ -1325,7 +1325,7 @@ TensorListVector* MasterGraph::create_caffe2_lmdb_record_meta_data_reader(const for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - auto tensor = new Tensor(info); + auto tensor = new Tensor(info, "label_" + get_tensor_uid()); _labels_tensor_list.push_back(tensor); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); @@ -1343,8 +1343,8 @@ TensorListVector* MasterGraph::create_caffe2_lmdb_record_meta_data_reader(const for (unsigned i = 0; i < _user_batch_size; i++) { auto labels_info = default_labels_info; auto bbox_info = default_bbox_info; - _labels_tensor_list.push_back(new Tensor(labels_info)); - _bbox_tensor_list.push_back(new Tensor(bbox_info)); + _labels_tensor_list.push_back(new Tensor(labels_info, "label_" + get_tensor_uid())); + _bbox_tensor_list.push_back(new Tensor(bbox_info, "bbox_" + get_tensor_uid())); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); _metadata_output_tensor_list.emplace_back(&_bbox_tensor_list); @@ -1373,7 +1373,7 @@ TensorListVector* MasterGraph::create_caffe_lmdb_record_meta_data_reader(const c for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - auto tensor = new Tensor(info); + auto tensor = new Tensor(info, "label_" + get_tensor_uid()); _labels_tensor_list.push_back(tensor); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); @@ -1391,8 +1391,8 @@ TensorListVector* MasterGraph::create_caffe_lmdb_record_meta_data_reader(const c for (unsigned i = 0; i < _user_batch_size; i++) { auto labels_info = default_labels_info; auto bbox_info = default_bbox_info; - _labels_tensor_list.push_back(new Tensor(labels_info)); - _bbox_tensor_list.push_back(new Tensor(bbox_info)); + _labels_tensor_list.push_back(new Tensor(labels_info, "label_" + get_tensor_uid())); + _bbox_tensor_list.push_back(new Tensor(bbox_info, "bbox_" + get_tensor_uid())); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); _metadata_output_tensor_list.emplace_back(&_bbox_tensor_list); @@ -1419,7 +1419,7 @@ TensorListVector* MasterGraph::create_cifar10_label_reader(const char *source_pa for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - auto tensor = new Tensor(info); + auto tensor = new Tensor(info, "label_" + get_tensor_uid()); _labels_tensor_list.push_back(tensor); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); @@ -1765,7 +1765,7 @@ void MasterGraph::feed_external_input(const std::vector& input_imag for (unsigned i = 0; i < _user_batch_size; i++) { auto info = default_labels_info; - _labels_tensor_list.push_back(new Tensor(info)); + _labels_tensor_list.push_back(new Tensor(info, "label_" + get_tensor_uid())); } _metadata_output_tensor_list.emplace_back(&_labels_tensor_list); } diff --git a/rocAL/source/pipeline/tensor.cpp b/rocAL/source/pipeline/tensor.cpp index 630c13a11..e2f6f9c56 100644 --- a/rocAL/source/pipeline/tensor.cpp +++ b/rocAL/source/pipeline/tensor.cpp @@ -285,7 +285,13 @@ Tensor::~Tensor() { Tensor::Tensor(const TensorInfo &tensor_info) : _info(tensor_info) { _info._type = TensorInfo::Type::UNKNOWN; - _tensor_name = "tensor_" + std::to_string(_tensor_idx++); + _mem_handle = nullptr; +} + +Tensor::Tensor(const TensorInfo &tensor_info, const std::string &name) + : _info(tensor_info) { + _info._type = TensorInfo::Type::UNKNOWN; + _tensor_name = "tensor_" + name; _mem_handle = nullptr; } From 4109ed43fcb06451a9da16622ddbaf324023e158 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 12 Nov 2025 04:00:55 -0600 Subject: [PATCH 079/118] Minor change --- rocAL/include/pipeline/tensor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/tensor.h b/rocAL/include/pipeline/tensor.h index eee5e7ac9..7ad648b6d 100644 --- a/rocAL/include/pipeline/tensor.h +++ b/rocAL/include/pipeline/tensor.h @@ -407,7 +407,7 @@ class TensorList : public rocalTensorList { Tensor* at(size_t index) override { return _tensor_list[index]; } void operator=(TensorList& other) { for (unsigned idx = 0; idx < other.size(); idx++) { - auto* new_tensor = new Tensor(other[idx]->info(), other[idx]->tensor_name() + "_1"); + auto* new_tensor = new Tensor(other[idx]->info(), other[idx]->tensor_name() + "_copy"); if (new_tensor->create_from_handle(other[idx]->context()) != 0) THROW("Cannot create the tensor from handle") this->push_back(new_tensor); From 798e1a139eb622cfdfed041882f9bbf10a8d4055 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 00:32:28 -0600 Subject: [PATCH 080/118] Resolve copilot review comments --- rocAL/include/pipeline/node.h | 2 +- rocAL/include/pipeline/pipeline_operator.h | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 2531843e6..2540f21c2 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -68,7 +68,7 @@ class Node { int _graph_id = -1; std::vector _args; template - void set_node_arguments(std::array& arg_names, std::index_sequence, Args... args) { + void set_node_arguments(const std::array& arg_names, std::index_sequence, Args... args) { // Fold expression to create Argument object for each argument in the node (this->_args.push_back(Argument(arg_names[Indices], std::forward(args))), ...); } diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index 105cd06f3..f0c5f7562 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -23,21 +23,20 @@ THE SOFTWARE. #pragma once #include +#include #include "pipeline/node.h" // Represents an operator in the pipeline class PipelineOperator { public: // Constructor to initialize the operator - explicit inline PipelineOperator(std::string op_name, std::string op_module_name, - std::shared_ptr op_node = nullptr) { - operator_name = op_name; // Set the operator's name - module_name = op_module_name; // Set the type/category of the operator - node = op_node; // Optional reference to the underlying node object + explicit inline PipelineOperator(const std::string& op_name, const std::string& op_module_name, + std::shared_ptr op_node = nullptr) + : operator_name(op_name), module_name(op_module_name), node(std::move(op_node)) { } // Set the list of arguments associated with this operator - void set_arguments(std::vector& op_arguments) { + void set_arguments(const std::vector& op_arguments) { arguments = op_arguments; } From d2aff1b6659c008ebbdcef0935b35589600cd817 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 00:45:17 -0600 Subject: [PATCH 081/118] Minor change --- rocAL/include/pipeline/pipeline_operator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index f0c5f7562..7350037f3 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -36,8 +36,8 @@ class PipelineOperator { } // Set the list of arguments associated with this operator - void set_arguments(const std::vector& op_arguments) { - arguments = op_arguments; + void set_arguments(const std::vector& arguments) { + this->arguments = arguments; } std::string operator_name; // Name of the operator (e.g., "ResizeNode") From f3f110c7ba8351b970feaf69f33868b0d9b3a608 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 01:36:31 -0600 Subject: [PATCH 082/118] Resolve copilot review comments --- rocAL/include/api/rocal_api.h | 8 +++++++- rocAL/include/pipeline/master_graph.h | 4 +++- rocAL/include/pipeline/pipeline_operator.h | 6 ++++++ rocAL/source/api/rocal_api.cpp | 5 ++++- rocAL/source/pipeline/master_graph.cpp | 3 +++ rocAL/source/pipeline/pipeline_serializer.cpp | 5 ++++- 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/rocAL/include/api/rocal_api.h b/rocAL/include/api/rocal_api.h index 7a4b03323..565d442de 100644 --- a/rocAL/include/api/rocal_api.h +++ b/rocAL/include/api/rocal_api.h @@ -126,8 +126,14 @@ extern "C" RocalStatus ROCAL_API_CALL rocalSerialize(RocalContext rocal_context, * into the user-provided buffer. The buffer must be pre-allocated with size * at least serialized_string_size + 1 bytes to accommodate the null terminator. * + * \warning The caller is responsible for ensuring the destination buffer has + * sufficient capacity (at least serialized_string_size + 1 bytes as returned by + * rocalSerialize). Passing an insufficiently sized buffer will result in buffer + * overflow and undefined behavior. + * * \param [in] rocal_context the rocAL context - * \param [out] serialized_string destination buffer to receive the serialized string (null-terminated) + * \param [out] serialized_string destination buffer to receive the serialized string (null-terminated). + * Must be pre-allocated with at least serialized_string_size + 1 bytes. * \return A \ref RocalStatus - A status code indicating the success or failure. */ extern "C" RocalStatus ROCAL_API_CALL rocalGetSerializedString(RocalContext rocal_context, char* serialized_string); diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index feb870dda..42f86633e 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -153,11 +153,13 @@ class MasterGraph { RocalTensorlayout layout, bool eos); void set_external_source_reader_flag() { _external_source_reader = true; } size_t bounding_box_batch_count(pMetaDataBatch meta_data_batch); - /** + /* * Serialize API */ void serialize(size_t *serialized_string_size); // Serialize the current pipeline to an internal string and return its size. + // Returns the last serialized pipeline string, Should be called after serialize(). Returns an empty string if serialize() hasn't been called. std::string& get_serialized_string() { return _serialized_pipeline; } + private: Status update_node_parameters(); void create_single_graph(); diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index c74ddc924..b74755128 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -58,6 +58,9 @@ class PipelineOperator { * Get the input tensors connected to the underlying node. */ const std::vector& get_inputs() const { + if (!this->node) { + THROW("get_inputs() called on operator with no associated node"); + } return this->node->input(); } @@ -65,6 +68,9 @@ class PipelineOperator { * Get the output tensors produced by the underlying node. */ const std::vector& get_outputs() const { + if (!this->node) { + THROW("get_outputs() called on operator with no associated node"); + } return this->node->output(); } diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index ac402e6ed..bdeeebe67 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -109,8 +109,11 @@ rocalVerify(RocalContext p_context) { RocalStatus ROCAL_API_CALL rocalSerialize(RocalContext rocal_context, size_t *serialized_string_size) { - auto context = static_cast(rocal_context); + auto context = static_cast(rocal_context); try { + if (!serialized_string_size) { + return ROCAL_INVALID_PARAMETER_TYPE; + } context->master_graph->serialize(serialized_string_size); } catch (const std::exception& e) { context->capture_error(e.what()); diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 1b5cafdf2..18a185984 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1794,6 +1794,9 @@ void MasterGraph::feed_external_input(const std::vector& input_imag } void MasterGraph::serialize(size_t *serialized_string_size) { + if (!serialized_string_size) { + THROW("serialized_string_size pointer is null"); + } _pipeline_serializer.reset(); _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth); _pipeline_serializer.serialize_operators(_pipeline_operators); diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 0f0f1b484..0b5675ab1 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -42,7 +42,7 @@ void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t ba _pipeline_proto.set_num_threads(num_threads); _pipeline_proto.set_batch_size(batch_size); _pipeline_proto.set_device_id(device_id); - _pipeline_proto.set_rocal_cpu(device_type == RocalMemType::HOST ? true : false); + _pipeline_proto.set_rocal_cpu(device_type == RocalMemType::HOST); _pipeline_proto.set_prefetch_queue_depth(prefetch_queue_depth); } @@ -77,6 +77,9 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& // rocal_proto::Parameter *param = arg->mutable_param(); // serialize_parameter_to_protobuf(param, op_arg); } else if (op_arg.type_name == "enum") { + if (op_arg.values.empty()) { + THROW("Enum argument " + op_arg.arg_name + " has no values"); + } rocal_proto::EnumType* enum_arg = arg->mutable_enum_value(); enum_arg->set_name(op_arg.sub_type_name); enum_arg->set_value(std::any_cast(op_arg.values[0])); From df5c6b95912d22f171f9f59533791b7fc3a02d40 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 02:54:30 -0600 Subject: [PATCH 083/118] Use uint64 in proto for pipeline members --- rocAL/proto/rocal.proto | 6 +++--- rocAL/source/pipeline/pipeline_serializer.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index 131d673ea..a0e0fc410 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -97,12 +97,12 @@ message OperatorDef { // Stores pipeline arguments and a list of nodes/operators message PipelineDef { - optional int64 num_threads = 1; - required int32 batch_size = 2; + optional uint64 num_threads = 1; + required uint64 batch_size = 2; optional int32 device_id = 3; optional int64 seed = 4; optional bool rocal_cpu = 5; - optional int32 prefetch_queue_depth = 6; + optional uint64 prefetch_queue_depth = 6; repeated OperatorDef operators = 7; repeated InputOutput pipe_outputs = 8; } diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index c6b98a938..64e0a4240 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -39,11 +39,11 @@ void PipelineSerializer::serialize_to_file(const std::string& file_path) { } void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth) { - _pipeline_proto.set_num_threads(num_threads); - _pipeline_proto.set_batch_size(batch_size); + _pipeline_proto.set_num_threads(static_cast(num_threads)); + _pipeline_proto.set_batch_size(static_cast(batch_size)); _pipeline_proto.set_device_id(device_id); _pipeline_proto.set_rocal_cpu(device_type == RocalMemType::HOST); - _pipeline_proto.set_prefetch_queue_depth(prefetch_queue_depth); + _pipeline_proto.set_prefetch_queue_depth(static_cast(prefetch_queue_depth)); } void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input) { From 1e79ae6a26fa624feed85b407c71e5752579eee3 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 03:12:15 -0600 Subject: [PATCH 084/118] Resolve review comments --- rocAL/include/parameters/parameter_random.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rocAL/include/parameters/parameter_random.h b/rocAL/include/parameters/parameter_random.h index 0491e7198..a1f0ee11f 100644 --- a/rocAL/include/parameters/parameter_random.h +++ b/rocAL/include/parameters/parameter_random.h @@ -105,7 +105,8 @@ class UniformRand : public Parameter { return (_start == _end); } - std::pair get_start_and_end() { + // Get the start and end values of the uniform random parameter. + std::pair get_start_and_end() const { return std::make_pair(_start, _end); } @@ -230,11 +231,14 @@ struct CustomRand : public Parameter { return (_values.size() == 1); } + // Get the values array for this CustomRand parameter. const std::vector& get_values() const { return _values; } + // Get the frequency/probability array for this CustomRand parameter. const std::vector& get_frequencies() const { return _frequencies; } - unsigned size() { return _size; } + // This method returns the current size of the parameter array managed by CustomRand. + unsigned size() const { return _size; } private: std::vector _values; //!< Values @@ -246,4 +250,4 @@ struct CustomRand : public Parameter { std::mt19937 _generator; std::mutex _lock; unsigned _size = 0; -}; \ No newline at end of file +}; From 6e1bfee1deeb72ce50652bb595e56bceb93fb326 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 03:14:39 -0600 Subject: [PATCH 085/118] Minor changes - review comments --- rocAL/include/pipeline/pipeline_operator.h | 2 +- rocAL/source/api/rocal_api.cpp | 2 +- rocAL/source/pipeline/pipeline_serializer.cpp | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index b74755128..b54a00224 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -46,7 +46,7 @@ class PipelineOperator { * For reader modules, arguments are stored directly on the operator. * For augmentation operators, the arguments are maintained by the underlying Node. */ - const std::vector& get_arguments() { + const std::vector& get_arguments() const { if (this->module_name == "reader") { return this->arguments; } else { diff --git a/rocAL/source/api/rocal_api.cpp b/rocAL/source/api/rocal_api.cpp index bdeeebe67..b4b592ca3 100644 --- a/rocAL/source/api/rocal_api.cpp +++ b/rocAL/source/api/rocal_api.cpp @@ -128,7 +128,7 @@ rocalGetSerializedString(RocalContext rocal_context, char* serialized_string) { auto context = static_cast(rocal_context); try { if (!serialized_string) { - THROW("String copy failed, Invalid pointer passed for serialize") + THROW("String copy failed, Invalid pointer passed for serialize.") } auto& serialize_pipe_string = context->master_graph->get_serialized_string(); diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 0b5675ab1..24a44c0a7 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -25,7 +25,9 @@ THE SOFTWARE. #include void PipelineSerializer::serialize_to_string(std::string& serialized_string) { - serialized_string = _pipeline_proto.SerializeAsString(); + if (!_pipeline_proto.SerializeToString(&serialized_string)) { + THROW("Failed to serialize pipeline to string."); + } } void PipelineSerializer::serialize_to_file(const std::string& file_path) { From 26b4502bc5ac4911a9d432666f8f364e22cf92c1 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 03:22:48 -0600 Subject: [PATCH 086/118] Add error check statements --- rocAL/source/pipeline/pipeline_serializer.cpp | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 64e0a4240..b5a12c934 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -87,9 +87,10 @@ template void serialize_simple_parameter(rocal_proto::Parameter *parameter, const Argument &op_arg) { auto param_core = extract_param_core(op_arg); auto simple_param = dynamic_cast *>(param_core); - if (simple_param) { - add_param_value(parameter, simple_param->get()); + if (!simple_param) { + THROW("Failed to cast parameter '" + op_arg.arg_name + "' to SimpleParameter type"); } + add_param_value(parameter, simple_param->get()); } // Template function to handle UniformRand serialization @@ -97,11 +98,12 @@ template void serialize_uniform_rand(rocal_proto::Parameter *parameter, const Argument &op_arg) { auto param_core = extract_param_core(op_arg); auto uniform_param = dynamic_cast *>(param_core); - if (uniform_param) { - auto uniform_range = uniform_param->get_start_and_end(); - add_param_value(parameter, uniform_range.first); - add_param_value(parameter, uniform_range.second); + if (!uniform_param) { + THROW("Failed to cast parameter '" + op_arg.arg_name + "' to UniformRand type"); } + auto uniform_range = uniform_param->get_start_and_end(); + add_param_value(parameter, uniform_range.first); + add_param_value(parameter, uniform_range.second); } // Template function to handle CustomRand serialization @@ -109,21 +111,22 @@ template void serialize_custom_rand(rocal_proto::Parameter *parameter, const Argument &op_arg) { auto param_core = extract_param_core(op_arg); auto random_param = dynamic_cast *>(param_core); - if (random_param) { - // Add values - auto values_vec = random_param->get_values(); - for (const auto &val : values_vec) { - add_param_value(parameter, val); - } - - // Add frequencies - auto frequency_vec = random_param->get_frequencies(); - for (const auto &val : frequency_vec) { - parameter->add_frequency(val); - } - - parameter->set_size(random_param->size()); + if (!random_param) { + THROW("Failed to cast parameter '" + op_arg.arg_name + "' to CustomRand type"); + } + // Add values + auto values_vec = random_param->get_values(); + for (const auto &val : values_vec) { + add_param_value(parameter, val); + } + + // Add frequencies + auto frequency_vec = random_param->get_frequencies(); + for (const auto &val : frequency_vec) { + parameter->add_frequency(val); } + + parameter->set_size(random_param->size()); } // Type dispatcher function to handle different data types From 72ff657b5e77f0ce04e55c84c38cde53bf3485f6 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 03:29:12 -0600 Subject: [PATCH 087/118] Revert input and outputs --- rocAL/include/pipeline/node.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 40df9a3ca..2540f21c2 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -39,8 +39,8 @@ class Node { virtual ~Node(); void create(std::shared_ptr graph); void update_parameters(); - const std::vector& input() const { return _inputs; } - const std::vector& output() const { return _outputs; } + std::vector input() { return _inputs; }; + std::vector output() { return _outputs; }; void add_next(const std::shared_ptr &node); // Adds the Node next to the current Node void add_previous(const std::shared_ptr &node); // Adds the Node preceding the current Node void release(); From d572f7fed9b7a81507d384b7cfdfd0cae54961a5 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 02:54:30 -0600 Subject: [PATCH 088/118] Use uint64 in proto for pipeline members --- rocAL/proto/rocal.proto | 6 +++--- rocAL/source/pipeline/pipeline_serializer.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index 5316a7391..d6c10a487 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -89,12 +89,12 @@ message OperatorDef { // Stores pipeline arguments and a list of nodes/operators message PipelineDef { - optional int64 num_threads = 1; - required int32 batch_size = 2; + optional uint64 num_threads = 1; + required uint64 batch_size = 2; optional int32 device_id = 3; optional int64 seed = 4; optional bool rocal_cpu = 5; - optional int32 prefetch_queue_depth = 6; + optional uint64 prefetch_queue_depth = 6; repeated OperatorDef operators = 7; repeated InputOutput pipe_outputs = 8; } diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 24a44c0a7..23929fd36 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -41,11 +41,11 @@ void PipelineSerializer::serialize_to_file(const std::string& file_path) { } void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth) { - _pipeline_proto.set_num_threads(num_threads); - _pipeline_proto.set_batch_size(batch_size); + _pipeline_proto.set_num_threads(static_cast(num_threads)); + _pipeline_proto.set_batch_size(static_cast(batch_size)); _pipeline_proto.set_device_id(device_id); _pipeline_proto.set_rocal_cpu(device_type == RocalMemType::HOST); - _pipeline_proto.set_prefetch_queue_depth(prefetch_queue_depth); + _pipeline_proto.set_prefetch_queue_depth(static_cast(prefetch_queue_depth)); } void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input) { From c6698afc417dc63151a60b76879ae0915a65c653 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 03:38:19 -0600 Subject: [PATCH 089/118] Revert "Revert input and outputs" This reverts commit 72ff657b5e77f0ce04e55c84c38cde53bf3485f6. --- rocAL/include/pipeline/node.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 2540f21c2..40df9a3ca 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -39,8 +39,8 @@ class Node { virtual ~Node(); void create(std::shared_ptr graph); void update_parameters(); - std::vector input() { return _inputs; }; - std::vector output() { return _outputs; }; + const std::vector& input() const { return _inputs; } + const std::vector& output() const { return _outputs; } void add_next(const std::shared_ptr &node); // Adds the Node next to the current Node void add_previous(const std::shared_ptr &node); // Adds the Node preceding the current Node void release(); From 1b7d8ed3c26034d1884d8b4d51960cc8e3ab0e38 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 03:59:29 -0600 Subject: [PATCH 090/118] Minor change --- tests/cpp_api/serialization_test/serialization_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 0f2c355f9..aa038a318 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -123,7 +123,7 @@ int main(int argc, const char **argv) { std::cout << "Serialized string size: " << serialized_string_size << " bytes" << std::endl; - // Allocate buffer for the serialized string + // Allocate buffer for the serialized string std::string serialized_pipe_string(serialized_string_size, '\0'); // Get the actual serialized string From 5100f7cb83e3712c11ff3b12c0119f8b79524272 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 18 Nov 2025 04:19:05 -0600 Subject: [PATCH 091/118] Minor changes --- rocAL/include/pipeline/master_graph.h | 1 + rocAL/include/pipeline/node.h | 6 ++++++ rocAL/include/pipeline/pipeline_operator.h | 12 +++++++++--- rocAL/source/loaders/image/node_image_loader.cpp | 1 - 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index 16ec78ea9..2fd8f62c8 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -168,6 +168,7 @@ class MasterGraph { bool no_more_processed_data(); // is_out_of_data() is called to check the remaining batch count from each loader module, if any of the loader module has consumed all the batches it returns true. bool is_out_of_data(); + // Generates a unique identifier for tensor naming by incrementing and returning the _tensor_idx counter. inline std::string get_tensor_uid() { return std::to_string(_tensor_idx++); } RingBuffer _ring_buffer; //!< The queue that keeps the tensors that have benn processed by the internal thread (_output_thread) asynchronous to the user's thread pMetaDataBatch _augmented_meta_data = nullptr; //!< The output of the meta_data_graph, diff --git a/rocAL/include/pipeline/node.h b/rocAL/include/pipeline/node.h index 2540f21c2..a1eb18312 100644 --- a/rocAL/include/pipeline/node.h +++ b/rocAL/include/pipeline/node.h @@ -67,6 +67,12 @@ class Node { std::vector> _prev; // Stores the reference to a list of previous Nodes int _graph_id = -1; std::vector _args; + /** + * @brief Template function to set node arguments using variadic templates and fold expressions. + * + * This function creates Argument objects for each argument-name pair and stores them in the node. + * It uses fold expressions to expand the parameter pack at compile time. + */ template void set_node_arguments(const std::array& arg_names, std::index_sequence, Args... args) { // Fold expression to create Argument object for each argument in the node diff --git a/rocAL/include/pipeline/pipeline_operator.h b/rocAL/include/pipeline/pipeline_operator.h index 7350037f3..794937fc5 100644 --- a/rocAL/include/pipeline/pipeline_operator.h +++ b/rocAL/include/pipeline/pipeline_operator.h @@ -26,12 +26,18 @@ THE SOFTWARE. #include #include "pipeline/node.h" -// Represents an operator in the pipeline +/** + * @brief Represents an operator in the pipeline for serialization purposes. + * + * This class encapsulates metadata about pipeline operators including their name, + * module category, arguments, and associated computational node. It is used to track + * and serialize pipeline structure. + */ class PipelineOperator { public: // Constructor to initialize the operator - explicit inline PipelineOperator(const std::string& op_name, const std::string& op_module_name, - std::shared_ptr op_node = nullptr) + explicit PipelineOperator(const std::string& op_name, const std::string& op_module_name, + std::shared_ptr op_node = nullptr) : operator_name(op_name), module_name(op_module_name), node(std::move(op_node)) { } diff --git a/rocAL/source/loaders/image/node_image_loader.cpp b/rocAL/source/loaders/image/node_image_loader.cpp index 755a74cdc..0e5d4635d 100644 --- a/rocAL/source/loaders/image/node_image_loader.cpp +++ b/rocAL/source/loaders/image/node_image_loader.cpp @@ -51,7 +51,6 @@ void ImageLoaderNode::init(unsigned internal_shard_count, unsigned cpu_num_threa reader_cfg.set_index_path(index_path); reader_cfg.set_sharding_info(sharding_info); - std::array arg_names = { "internal_shard_count", "cpu_num_threads", "source_path", "json_path", "feature_key_map", "storage_type", "decoder_type", From 0128dab04939f8e85a5d7273c49d76fee1e6839a Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 9 Dec 2025 01:23:56 -0600 Subject: [PATCH 092/118] Return tensor name as reference --- rocAL/include/pipeline/tensor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocAL/include/pipeline/tensor.h b/rocAL/include/pipeline/tensor.h index 7ad648b6d..1c51d78ab 100644 --- a/rocAL/include/pipeline/tensor.h +++ b/rocAL/include/pipeline/tensor.h @@ -377,7 +377,7 @@ class Tensor : public rocalTensor { return (_info.mem_type() == RocalMemType::HOST ? ROCAL_CPU : ROCAL_GPU); } uint64_t data_type_size() override { return _info.data_type_size(); } - std::string tensor_name() { return _tensor_name; } + const std::string& tensor_name() const { return _tensor_name; } private: vx_tensor _vx_handle = nullptr; //!< The OpenVX tensor void* _mem_handle = nullptr; //!< Pointer to the tensor's internal buffer (opencl or host) From e817a47ce61a16b620952ce81a696315e33e926d Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Wed, 10 Dec 2025 04:44:19 -0600 Subject: [PATCH 093/118] Remove type string from InputOutput proto --- rocAL/proto/rocal.proto | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/rocAL/proto/rocal.proto b/rocAL/proto/rocal.proto index d6c10a487..fff43ff68 100644 --- a/rocAL/proto/rocal.proto +++ b/rocAL/proto/rocal.proto @@ -27,14 +27,13 @@ package rocal_proto; // Stores the Input/Output tensors message InputOutput { required string name = 1; - optional string type = 2; - required bool is_argument_input = 3; - required int32 device = 4; - optional int32 dtype = 5; - optional int32 layout = 6; - optional int32 color_format = 7; - repeated uint64 dims = 8; - required uint32 num_dims = 9; + required bool is_argument_input = 2; + required int32 device = 3; + optional int32 dtype = 4; + optional int32 layout = 5; + optional int32 color_format = 6; + repeated uint64 dims = 7; + required uint32 num_dims = 8; } message EnumType { From 7374112e3e553bd8e1e023627068d3ace8b8826a Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 00:20:52 -0600 Subject: [PATCH 094/118] Add python support for rocAL serialize --- rocAL_pybind/amd/rocal/pipeline.py | 9 ++++++++- rocAL_pybind/rocal_pybind.cpp | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/rocAL_pybind/amd/rocal/pipeline.py b/rocAL_pybind/amd/rocal/pipeline.py index 14d0ac74d..7e579cf40 100644 --- a/rocAL_pybind/amd/rocal/pipeline.py +++ b/rocAL_pybind/amd/rocal/pipeline.py @@ -272,7 +272,14 @@ def run(self): return b.getOutputTensors(self._handle) except: raise StopIteration - + + def serialize(self): + """ + Serialize the pipeline and stores into protobuffers + return: + The serialized string of the pipeline object + """ + return b.rocalSerialize(self._handle) def _discriminate_args(func, **func_kwargs): """!Split args on those applicable to Pipeline constructor and the decorated function.""" diff --git a/rocAL_pybind/rocal_pybind.cpp b/rocAL_pybind/rocal_pybind.cpp index 10a7a6c1f..6a8e162df 100644 --- a/rocAL_pybind/rocal_pybind.cpp +++ b/rocAL_pybind/rocal_pybind.cpp @@ -294,6 +294,13 @@ PYBIND11_MODULE(rocal_pybind, m) { m.def("rocalVerify", &rocalVerify); m.def("rocalRun", &rocalRun, py::return_value_policy::reference); m.def("rocalRelease", &rocalRelease, py::return_value_policy::reference); + m.def("rocalSerialize", [](RocalContext context) { + size_t size; + rocalSerialize(context, size); + std::string serialized_string(size, '\0'); + rocalGetSerializedString(context, serialized_string.c_str()); + return py::bytes(serialized_string); // Returned by value + }, "Returns the serialized pipeline as string"); // rocal_api_types.h py::class_(m, "TimingInfo") .def_readwrite("load_time", &TimingInfo::load_time) From 150c240902b60aaacdb46f3fc366e91823e0e6a0 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 00:29:40 -0600 Subject: [PATCH 095/118] Accept filename as input --- rocAL_pybind/amd/rocal/pipeline.py | 8 ++++++-- rocAL_pybind/rocal_pybind.cpp | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/rocAL_pybind/amd/rocal/pipeline.py b/rocAL_pybind/amd/rocal/pipeline.py index 7e579cf40..40161cff2 100644 --- a/rocAL_pybind/amd/rocal/pipeline.py +++ b/rocAL_pybind/amd/rocal/pipeline.py @@ -273,13 +273,17 @@ def run(self): except: raise StopIteration - def serialize(self): + def serialize(self, filename=None): """ Serialize the pipeline and stores into protobuffers return: The serialized string of the pipeline object """ - return b.rocalSerialize(self._handle) + serialized_str = b.serializePipeline(self._handle) + if filename: + with open(filename, 'wb') as f: + f.write(serialized_str) + return serialized_str def _discriminate_args(func, **func_kwargs): """!Split args on those applicable to Pipeline constructor and the decorated function.""" diff --git a/rocAL_pybind/rocal_pybind.cpp b/rocAL_pybind/rocal_pybind.cpp index 6a8e162df..8801dc8c6 100644 --- a/rocAL_pybind/rocal_pybind.cpp +++ b/rocAL_pybind/rocal_pybind.cpp @@ -296,9 +296,9 @@ PYBIND11_MODULE(rocal_pybind, m) { m.def("rocalRelease", &rocalRelease, py::return_value_policy::reference); m.def("rocalSerialize", [](RocalContext context) { size_t size; - rocalSerialize(context, size); + rocalSerialize(context, &size); std::string serialized_string(size, '\0'); - rocalGetSerializedString(context, serialized_string.c_str()); + rocalGetSerializedString(context, serialized_string.data()); return py::bytes(serialized_string); // Returned by value }, "Returns the serialized pipeline as string"); // rocal_api_types.h From 5bd3687d36a34e310850e62ff4d2c3d9ff6c8913 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 01:58:20 -0600 Subject: [PATCH 096/118] Introduce python serialization test file --- rocAL_pybind/amd/rocal/pipeline.py | 2 +- tests/python_api/pipeline_serialize_test.py | 216 ++++++++++++++++++++ 2 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 tests/python_api/pipeline_serialize_test.py diff --git a/rocAL_pybind/amd/rocal/pipeline.py b/rocAL_pybind/amd/rocal/pipeline.py index 40161cff2..7e9b806d3 100644 --- a/rocAL_pybind/amd/rocal/pipeline.py +++ b/rocAL_pybind/amd/rocal/pipeline.py @@ -279,7 +279,7 @@ def serialize(self, filename=None): return: The serialized string of the pipeline object """ - serialized_str = b.serializePipeline(self._handle) + serialized_str = b.rocalSerialize(self._handle) if filename: with open(filename, 'wb') as f: f.write(serialized_str) diff --git a/tests/python_api/pipeline_serialize_test.py b/tests/python_api/pipeline_serialize_test.py new file mode 100644 index 000000000..c4ece6a1f --- /dev/null +++ b/tests/python_api/pipeline_serialize_test.py @@ -0,0 +1,216 @@ +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import random +import sys +import os +import cv2 +import tempfile +from amd.rocal.plugin.pytorch import ROCALClassificationIterator +from amd.rocal.pipeline import Pipeline +import amd.rocal.fn as fn +import amd.rocal.types as types + + +def save_output_images(img, idx, output_dir, device=True, layout="NCHW"): + """Save output images for verification""" + import cv2 + if device is False: + image = img.cpu().numpy() + else: + image = img.numpy() + if layout == "NCHW": + image = image.transpose([1, 2, 0]) + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + cv2.imwrite(os.path.join(output_dir, f"serialize_test_{idx}.png"), image) + + +def create_test_pipeline(data_path, rocal_cpu=True, batch_size=2): + """Create a test pipeline with supported augmentations""" + num_threads = 1 + device_id = 0 + random_seed = random.SystemRandom().randint(0, 2**32 - 1) + local_rank = 0 + world_size = 1 + + # Create pipeline + pipeline = Pipeline( + batch_size=batch_size, + num_threads=num_threads, + device_id=device_id, + seed=random_seed, + rocal_cpu=rocal_cpu + ) + + with pipeline: + # File reader + jpegs, labels = fn.readers.file(file_root=data_path) + + # Image decoder + decode = fn.decoders.image( + jpegs, + output_type=types.RGB, + file_root=data_path, + shard_id=local_rank, + num_shards=world_size, + random_shuffle=True + ) + + # Brightness augmentation + brightness = fn.brightness( + decode, + brightness=0.5, + output_layout=types.NCHW, + output_dtype=types.UINT8 + ) + + pipeline.set_outputs(brightness) + + return pipeline + + +def test_pipeline_serialization(data_path, rocal_cpu=True, batch_size=2): + """Test pipeline serialization functionality""" + print(f">>> Testing Pipeline Serialization on {'CPU' if rocal_cpu else 'GPU'}") + + # Create output directory + output_dir = "output_folder/serialize_test" + try: + os.makedirs(output_dir, exist_ok=True) + except OSError as error: + print(f"Error creating output directory: {error}") + return False + + try: + # Create and build pipeline + print("Creating test pipeline...") + pipeline = create_test_pipeline(data_path, rocal_cpu, batch_size) + pipeline.build() + + # Test serialization + print("\n=== Testing Pipeline Serialization ===") + + # Test 1: Serialize to string + print("Test 1: Serializing pipeline to string...") + serialized_string = pipeline.serialize() + + if serialized_string is None or len(serialized_string) == 0: + print("ERROR: Failed to serialize pipeline - empty result") + return False + + print(f"Serialized string size: {len(serialized_string)} bytes") + print("Serialization to string: SUCCESS") + + # Test 2: Serialize to file + print("\nTest 2: Serializing pipeline to file...") + serialize_file = os.path.join(output_dir, "pipeline_serialized.bin") + serialized_string_file = pipeline.serialize(filename=serialize_file) + + if not os.path.exists(serialize_file): + print("ERROR: Serialized file was not created") + return False + + print(f"Serialized file created: {serialize_file}") + print(f"File size: {os.path.getsize(serialize_file)} bytes") + print("Serialization to file: SUCCESS") + + # Test 3: Display serialized content (first 500 chars for readability) + print("\n=== Serialized Pipeline Content (Preview) ===") + try: + # Try to decode as text for preview + preview_text = serialized_string.decode('utf-8', errors='ignore')[:500] + print(preview_text) + if len(serialized_string) > 500: + print("... (truncated)") + except: + # If binary, show hex representation + print("Binary content (hex preview):") + print(serialized_string[:100].hex()) + if len(serialized_string) > 100: + print("... (truncated)") + print("=== End of Serialized Content Preview ===") + + # Test 4: Test pipeline execution after serialization + print("\n=== Testing Pipeline Execution After Serialization ===") + + # Create iterator and run a few iterations + imageIteratorPipeline = ROCALClassificationIterator(pipeline) + + print(f"Available images: {pipeline.get_remaining_images()}") + + iteration_count = 0 + for i, batch_data in enumerate(imageIteratorPipeline): + + print(f"\nIteration {iteration_count + 1}:") + images, labels = batch_data + + print(f" Batch shape: {images[0].shape} images") + print(f" Labels: {labels}") + + # Save a sample image from the batch + if len(images) > 0: + save_output_images( + images[0][0], + iteration_count, + output_dir, + device=rocal_cpu, + layout="NCHW" + ) + + iteration_count += 1 + + imageIteratorPipeline.reset() + print("Pipeline execution after serialization: SUCCESS") + return True + + except Exception as e: + print(f"ERROR: Exception during serialization test: {str(e)}") + import traceback + traceback.print_exc() + return False + + +def main(): + """Main function to run serialization tests""" + if len(sys.argv) < 2: + print('Usage: python pipeline_serialize_test.py [cpu/gpu] [batch_size]') + sys.exit(1) + + # Parse arguments + data_path = sys.argv[1] + rocal_cpu = True if len(sys.argv) < 3 or sys.argv[2] == "cpu" else False + batch_size = int(sys.argv[3]) if len(sys.argv) > 3 else 2 + + # Validate data path + if not os.path.exists(data_path): + print(f"ERROR: Data path does not exist: {data_path}") + sys.exit(1) + + # Run the test + success = test_pipeline_serialization(data_path, rocal_cpu, batch_size) + + if success: + print("SERIALIZATION TESTS PASSED!") + else: + print("SERIALIZATION TESTS FAILED") + + +if __name__ == '__main__': + main() From ff7a970fda40dd5a0bfe21a49be8d4f159163a53 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 29 Jul 2025 09:36:00 +0000 Subject: [PATCH 097/118] Add support to store and fetch seed value in proto --- rocAL/include/pipeline/pipeline_serializer.h | 2 +- rocAL/source/pipeline/master_graph.cpp | 2 +- rocAL/source/pipeline/pipeline_serializer.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h index 57d2cf521..5d91a6777 100644 --- a/rocAL/include/pipeline/pipeline_serializer.h +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -55,7 +55,7 @@ class PipelineSerializer { /** * @brief Serialize global pipeline configuration. */ - void serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth); + void serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth, size_t seed); /** * @brief Serialize pipeline output tensors (shape, dtype, device, layout). */ diff --git a/rocAL/source/pipeline/master_graph.cpp b/rocAL/source/pipeline/master_graph.cpp index 18a185984..bba962a95 100644 --- a/rocAL/source/pipeline/master_graph.cpp +++ b/rocAL/source/pipeline/master_graph.cpp @@ -1798,7 +1798,7 @@ void MasterGraph::serialize(size_t *serialized_string_size) { THROW("serialized_string_size pointer is null"); } _pipeline_serializer.reset(); - _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth); + _pipeline_serializer.serialize_pipeline_config(_cpu_num_threads, _user_batch_size, _gpu_id, _mem_type, _prefetch_queue_depth, ParameterFactory::instance()->get_seed()); _pipeline_serializer.serialize_operators(_pipeline_operators); _pipeline_serializer.serialize_output_tensors(_internal_tensor_list); _pipeline_serializer.serialize_to_string(_serialized_pipeline); diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 23929fd36..642e72d99 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -40,12 +40,13 @@ void PipelineSerializer::serialize_to_file(const std::string& file_path) { } } -void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth) { +void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth, size_t seed) { _pipeline_proto.set_num_threads(static_cast(num_threads)); _pipeline_proto.set_batch_size(static_cast(batch_size)); _pipeline_proto.set_device_id(device_id); _pipeline_proto.set_rocal_cpu(device_type == RocalMemType::HOST); _pipeline_proto.set_prefetch_queue_depth(static_cast(prefetch_queue_depth)); + _pipeline_proto.set_seed(static_cast(seed)); } void set_tensor_proto(rocal_proto::InputOutput *in_out_proto, Tensor *tensor, bool is_input) { From 1cd771063a02f3e8c4902330e70fde7e72055ad5 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 05:39:33 -0600 Subject: [PATCH 098/118] Remove serialize to file --- rocAL/include/pipeline/pipeline_serializer.h | 6 ------ rocAL/source/pipeline/pipeline_serializer.cpp | 10 ---------- 2 files changed, 16 deletions(-) diff --git a/rocAL/include/pipeline/pipeline_serializer.h b/rocAL/include/pipeline/pipeline_serializer.h index 5d91a6777..b777049b3 100644 --- a/rocAL/include/pipeline/pipeline_serializer.h +++ b/rocAL/include/pipeline/pipeline_serializer.h @@ -40,12 +40,6 @@ class PipelineSerializer { ~PipelineSerializer() {} // Serialization methods - /** - * @brief Serialize the current PipelineDef into a file on disk. - * @param file_path Path to save the serialized pipeline (binary payload) - */ - void serialize_to_file(const std::string& file_path); - /** * @brief Serialize the current PipelineDef into a binary string. * @param serialized_string Output string containing the serialized pipeline diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 642e72d99..e48ff6026 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -30,16 +30,6 @@ void PipelineSerializer::serialize_to_string(std::string& serialized_string) { } } -void PipelineSerializer::serialize_to_file(const std::string& file_path) { - std::ofstream ofs(file_path, std::ios::binary); - if (!ofs) { - THROW("Failed to open file for writing serialized pipeline: " + file_path); - } - if (!_pipeline_proto.SerializeToOstream(&ofs)) { - THROW("Failed to serialize pipeline to file: " + file_path); - } -} - void PipelineSerializer::serialize_pipeline_config(size_t num_threads, size_t batch_size, int device_id, RocalMemType device_type, size_t prefetch_queue_depth, size_t seed) { _pipeline_proto.set_num_threads(static_cast(num_threads)); _pipeline_proto.set_batch_size(static_cast(batch_size)); From f904406d4e3b49b284e1a41dc8e86901702668a2 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 05:23:32 -0600 Subject: [PATCH 099/118] Register copy node --- rocAL/source/augmentations/node_copy.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rocAL/source/augmentations/node_copy.cpp b/rocAL/source/augmentations/node_copy.cpp index 38dd07431..0ed380c68 100644 --- a/rocAL/source/augmentations/node_copy.cpp +++ b/rocAL/source/augmentations/node_copy.cpp @@ -27,6 +27,8 @@ THE SOFTWARE. #include "pipeline/exception.h" #include "augmentations/node_copy.h" +REGISTER_NODE(CopyNode) + CopyNode::CopyNode(const std::vector &inputs, const std::vector &outputs) : Node(inputs, outputs) {} void CopyNode::create_node() { From 74b81f9f027ea60c5dd7b816e83512d615c8c39d Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 05:33:21 -0600 Subject: [PATCH 100/118] Add serialization support for ImageLoaderSingleShardNode --- .../image/node_image_loader_single_shard.h | 3 ++- rocAL/include/pipeline/master_graph.h | 4 ++++ .../image/node_image_loader_single_shard.cpp | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/rocAL/include/loaders/image/node_image_loader_single_shard.h b/rocAL/include/loaders/image/node_image_loader_single_shard.h index aefe80e5e..091797104 100644 --- a/rocAL/include/loaders/image/node_image_loader_single_shard.h +++ b/rocAL/include/loaders/image/node_image_loader_single_shard.h @@ -41,6 +41,7 @@ class ImageLoaderSingleShardNode : public Node { const std::map feature_key_map = std::map(), unsigned sequence_length = 0, unsigned step = 0, unsigned stride = 0, ExternalSourceFileMode external_file_mode = ExternalSourceFileMode::NONE, const std::string &index_path = ""); std::shared_ptr get_loader_module(); + std::string node_name() const override { return "ImageLoaderSingleShardNode"; } protected: void create_node() override{}; @@ -48,4 +49,4 @@ class ImageLoaderSingleShardNode : public Node { private: std::shared_ptr _loader_module = nullptr; -}; \ No newline at end of file +}; diff --git a/rocAL/include/pipeline/master_graph.h b/rocAL/include/pipeline/master_graph.h index f7fd3844d..95fd41da5 100644 --- a/rocAL/include/pipeline/master_graph.h +++ b/rocAL/include/pipeline/master_graph.h @@ -326,6 +326,10 @@ inline std::shared_ptr MasterGraph::add_node(const s _loader_modules.emplace_back(loader_module); node->set_graph_id(_loaders_count++); _root_nodes.push_back(node); + + // Add each operator to the pipeline operators list + _pipeline_operators.push_back(std::make_shared(node->node_name() + "_" + std::to_string(_op_idx++), "loader", node)); + for (auto &output : outputs) _tensor_map.insert(std::make_pair(output, node)); diff --git a/rocAL/source/loaders/image/node_image_loader_single_shard.cpp b/rocAL/source/loaders/image/node_image_loader_single_shard.cpp index 7c2c44644..7223bc23e 100644 --- a/rocAL/source/loaders/image/node_image_loader_single_shard.cpp +++ b/rocAL/source/loaders/image/node_image_loader_single_shard.cpp @@ -52,6 +52,23 @@ void ImageLoaderSingleShardNode::init(unsigned shard_id, unsigned shard_count, u reader_cfg.set_external_filemode(external_file_mode); reader_cfg.set_index_path(index_path); reader_cfg.set_sharding_info(sharding_info); + + std::array arg_names = { + "shard_id", "shard_count", "cpu_num_threads", "source_path", + "json_path", "storage_type", "decoder_type", "shuffle", "loop", + "load_batch_count", "mem_type", "meta_data_reader", "decoder_keep_orig", + "last_batch_policy", "pad_last_batch_repeated", "stick_to_shard", "shard_size", + "feature_key_map", "sequence_length", "step", "stride", + "external_file_mode", "index_path" + }; + + set_node_arguments(arg_names, std::make_index_sequence{}, shard_id, + shard_count, cpu_num_threads, source_path, json_path, storage_type, + decoder_type, shuffle, loop, load_batch_count, mem_type, meta_data_reader, decoder_keep_original, + sharding_info.last_batch_policy, sharding_info.pad_last_batch_repeated, + sharding_info.stick_to_shard, sharding_info.shard_size, feature_key_map, + sequence_length, step, stride, external_file_mode, index_path); + _loader_module->initialize(reader_cfg, DecoderConfig(decoder_type), mem_type, _batch_size, decoder_keep_original); From bd5cd3aa9dc30cd41fcf050e203b46b4012430da Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 05:46:20 -0600 Subject: [PATCH 101/118] Revert "Register copy node" This reverts commit f904406d4e3b49b284e1a41dc8e86901702668a2. --- rocAL/source/augmentations/node_copy.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/rocAL/source/augmentations/node_copy.cpp b/rocAL/source/augmentations/node_copy.cpp index 0ed380c68..38dd07431 100644 --- a/rocAL/source/augmentations/node_copy.cpp +++ b/rocAL/source/augmentations/node_copy.cpp @@ -27,8 +27,6 @@ THE SOFTWARE. #include "pipeline/exception.h" #include "augmentations/node_copy.h" -REGISTER_NODE(CopyNode) - CopyNode::CopyNode(const std::vector &inputs, const std::vector &outputs) : Node(inputs, outputs) {} void CopyNode::create_node() { From ccf207e96f2dcb9d9bf74237292fa4990cf8004b Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 05:52:44 -0600 Subject: [PATCH 102/118] Update python test file --- tests/python_api/pipeline_serialize_test.py | 45 ++++++++------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/tests/python_api/pipeline_serialize_test.py b/tests/python_api/pipeline_serialize_test.py index c4ece6a1f..6ddba79ef 100644 --- a/tests/python_api/pipeline_serialize_test.py +++ b/tests/python_api/pipeline_serialize_test.py @@ -86,8 +86,8 @@ def create_test_pipeline(data_path, rocal_cpu=True, batch_size=2): return pipeline -def test_pipeline_serialization(data_path, rocal_cpu=True, batch_size=2): - """Test pipeline serialization functionality""" +def test_serialization(data_path, rocal_cpu=True, batch_size=2): + """Test pipeline serialization functionality and return serialized string""" print(f">>> Testing Pipeline Serialization on {'CPU' if rocal_cpu else 'GPU'}") # Create output directory @@ -96,42 +96,29 @@ def test_pipeline_serialization(data_path, rocal_cpu=True, batch_size=2): os.makedirs(output_dir, exist_ok=True) except OSError as error: print(f"Error creating output directory: {error}") - return False + return None try: # Create and build pipeline print("Creating test pipeline...") pipeline = create_test_pipeline(data_path, rocal_cpu, batch_size) pipeline.build() - + # Test serialization print("\n=== Testing Pipeline Serialization ===") - # Test 1: Serialize to string + # Test Serialize to string print("Test 1: Serializing pipeline to string...") serialized_string = pipeline.serialize() if serialized_string is None or len(serialized_string) == 0: print("ERROR: Failed to serialize pipeline - empty result") - return False + return None print(f"Serialized string size: {len(serialized_string)} bytes") print("Serialization to string: SUCCESS") - # Test 2: Serialize to file - print("\nTest 2: Serializing pipeline to file...") - serialize_file = os.path.join(output_dir, "pipeline_serialized.bin") - serialized_string_file = pipeline.serialize(filename=serialize_file) - - if not os.path.exists(serialize_file): - print("ERROR: Serialized file was not created") - return False - - print(f"Serialized file created: {serialize_file}") - print(f"File size: {os.path.getsize(serialize_file)} bytes") - print("Serialization to file: SUCCESS") - - # Test 3: Display serialized content (first 500 chars for readability) + # Display serialized content (first 500 chars for readability) print("\n=== Serialized Pipeline Content (Preview) ===") try: # Try to decode as text for preview @@ -147,12 +134,10 @@ def test_pipeline_serialization(data_path, rocal_cpu=True, batch_size=2): print("... (truncated)") print("=== End of Serialized Content Preview ===") - # Test 4: Test pipeline execution after serialization + # Test pipeline execution after serialization print("\n=== Testing Pipeline Execution After Serialization ===") - # Create iterator and run a few iterations imageIteratorPipeline = ROCALClassificationIterator(pipeline) - print(f"Available images: {pipeline.get_remaining_images()}") iteration_count = 0 @@ -164,21 +149,22 @@ def test_pipeline_serialization(data_path, rocal_cpu=True, batch_size=2): print(f" Batch shape: {images[0].shape} images") print(f" Labels: {labels}") - # Save a sample image from the batch + # Save output images if len(images) > 0: save_output_images( images[0][0], - iteration_count, + f"serialization_{iteration_count}", output_dir, device=rocal_cpu, layout="NCHW" ) + print(f" Saved output image: serialization_{iteration_count}.png") iteration_count += 1 imageIteratorPipeline.reset() - print("Pipeline execution after serialization: SUCCESS") - return True + print("\n=== Serialization Test Completed Successfully ===") + return serialized_string except Exception as e: print(f"ERROR: Exception during serialization test: {str(e)}") @@ -203,8 +189,9 @@ def main(): print(f"ERROR: Data path does not exist: {data_path}") sys.exit(1) - # Run the test - success = test_pipeline_serialization(data_path, rocal_cpu, batch_size) + # Run the serialization test + serialized_string = test_serialization(data_path, rocal_cpu, batch_size) + success = serialized_string is not None if success: print("SERIALIZATION TESTS PASSED!") From ea47d3a3170f8945a74d8f75895c51f4ed819bec Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 11:36:23 -0600 Subject: [PATCH 103/118] Minor changes --- rocAL_pybind/amd/rocal/pipeline.py | 2 +- tests/python_api/pipeline_serialize_test.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/rocAL_pybind/amd/rocal/pipeline.py b/rocAL_pybind/amd/rocal/pipeline.py index 7e9b806d3..7b6f94353 100644 --- a/rocAL_pybind/amd/rocal/pipeline.py +++ b/rocAL_pybind/amd/rocal/pipeline.py @@ -275,7 +275,7 @@ def run(self): def serialize(self, filename=None): """ - Serialize the pipeline and stores into protobuffers + Serialize the pipeline and store into protobuffers return: The serialized string of the pipeline object """ diff --git a/tests/python_api/pipeline_serialize_test.py b/tests/python_api/pipeline_serialize_test.py index 6ddba79ef..fb8dcb74e 100644 --- a/tests/python_api/pipeline_serialize_test.py +++ b/tests/python_api/pipeline_serialize_test.py @@ -22,16 +22,13 @@ import sys import os import cv2 -import tempfile from amd.rocal.plugin.pytorch import ROCALClassificationIterator from amd.rocal.pipeline import Pipeline import amd.rocal.fn as fn import amd.rocal.types as types - def save_output_images(img, idx, output_dir, device=True, layout="NCHW"): """Save output images for verification""" - import cv2 if device is False: image = img.cpu().numpy() else: From e42c9e1e7f9e3096833d7abe80e9be012339111c Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Thu, 11 Dec 2025 12:56:22 -0600 Subject: [PATCH 104/118] Fix the size of char buffer and other minor fixes --- rocAL_pybind/amd/rocal/pipeline.py | 8 ++++++-- rocAL_pybind/rocal_pybind.cpp | 17 +++++++++++++---- tests/python_api/pipeline_serialize_test.py | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/rocAL_pybind/amd/rocal/pipeline.py b/rocAL_pybind/amd/rocal/pipeline.py index 7b6f94353..0929cbb47 100644 --- a/rocAL_pybind/amd/rocal/pipeline.py +++ b/rocAL_pybind/amd/rocal/pipeline.py @@ -276,8 +276,12 @@ def run(self): def serialize(self, filename=None): """ Serialize the pipeline and store into protobuffers - return: - The serialized string of the pipeline object + + Args: + filename (str, optional): Optional output path to write the serialized data to file + + Returns: + bytes: The serialized pipeline as protobuf payload """ serialized_str = b.rocalSerialize(self._handle) if filename: diff --git a/rocAL_pybind/rocal_pybind.cpp b/rocAL_pybind/rocal_pybind.cpp index 8801dc8c6..881ef323f 100644 --- a/rocAL_pybind/rocal_pybind.cpp +++ b/rocAL_pybind/rocal_pybind.cpp @@ -296,10 +296,19 @@ PYBIND11_MODULE(rocal_pybind, m) { m.def("rocalRelease", &rocalRelease, py::return_value_policy::reference); m.def("rocalSerialize", [](RocalContext context) { size_t size; - rocalSerialize(context, &size); - std::string serialized_string(size, '\0'); - rocalGetSerializedString(context, serialized_string.data()); - return py::bytes(serialized_string); // Returned by value + RocalStatus status = rocalSerialize(context, &size); + if (status != ROCAL_OK) { + throw std::runtime_error("Failed to serialize pipeline"); + } + // Allocate size+1 bytes to handle null terminator safely + std::vector buffer(size + 1, '\0'); + status = rocalGetSerializedString(context, buffer.data()); + if (status != ROCAL_OK) { + throw std::runtime_error("Failed to get serialized string"); + } + + // Return only the first 'size' bytes as Python bytes object + return py::bytes(buffer.data(), size); }, "Returns the serialized pipeline as string"); // rocal_api_types.h py::class_(m, "TimingInfo") diff --git a/tests/python_api/pipeline_serialize_test.py b/tests/python_api/pipeline_serialize_test.py index fb8dcb74e..5dfd39a60 100644 --- a/tests/python_api/pipeline_serialize_test.py +++ b/tests/python_api/pipeline_serialize_test.py @@ -167,7 +167,7 @@ def test_serialization(data_path, rocal_cpu=True, batch_size=2): print(f"ERROR: Exception during serialization test: {str(e)}") import traceback traceback.print_exc() - return False + return None def main(): @@ -178,7 +178,7 @@ def main(): # Parse arguments data_path = sys.argv[1] - rocal_cpu = True if len(sys.argv) < 3 or sys.argv[2] == "cpu" else False + rocal_cpu = (sys.argv[2].lower() == "cpu") if len(sys.argv) > 2 else True batch_size = int(sys.argv[3]) if len(sys.argv) > 3 else 2 # Validate data path From 4ecb3ee4f542babee8e3d5b7894715d236b8a314 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 16 Dec 2025 03:36:13 -0600 Subject: [PATCH 105/118] Update CHANGELOG --- CHANGELOG.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b13564479..c61d73b07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/projects/rocAL/](https://rocm.docs.amd.com/projects/rocAL/en/latest/). +## (Unreleased) rocAL 2.6.0 + +### Added +* `PipelineSerializer` class to implement pipeline serialization functionality in rocAL. + +### Changes +* Adds new public APIs rocalSerialize() and rocalGetSerializedString() for serializing pipelines. +* Add support to store the pipeline into protobuf format. + +### Removed + + ## rocAL 2.5.0 for ROCm 7.2.0 ### Added @@ -9,7 +21,6 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro * `Argument` class which stores the value and type of each argument in the Node. * Support to store the arguments in the Node class. * `PipelineOperator` class to represent operators in the pipeline with metadata. -* `PipelineSerializer` class to implement pipeline serialization functionality in rocAL. ### Changes * OpenCL backend support - deprecated @@ -17,8 +28,6 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro * Refactor external enum usage in rocAL, to maintain separation between external and internal enums. * Introduced the following enums ResizeScalingMode, ResizeInterpolationType, MelScaleFormula, AudioBorderType, OutOfBoundsPolicy in commons.h. * Adds support to track operators in MasterGraph with unique naming. -* Adds new public APIs rocalSerialize() and rocalGetSerializedString() for serializing pipelines. -* Add support to store the pipeline into protobuf format. ### Resolved issues * Use HIP memory for fused crop rocjpeg decoder From 7af03beea6d63afb60aaf1e7e6d9d5451ecf2fb9 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 16 Dec 2025 03:42:58 -0600 Subject: [PATCH 106/118] Add period in throw statements --- rocAL/source/pipeline/pipeline_serializer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 571daaad8..11571adcc 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -81,7 +81,7 @@ void serialize_simple_parameter(rocal_proto::Parameter *parameter, const Argumen auto param_core = extract_param_core(op_arg); auto simple_param = dynamic_cast *>(param_core); if (!simple_param) { - THROW("Failed to cast parameter '" + op_arg.arg_name + "' to SimpleParameter type"); + THROW("Failed to cast parameter '" + op_arg.arg_name + "' to SimpleParameter type."); } add_param_value(parameter, simple_param->get()); } @@ -92,7 +92,7 @@ void serialize_uniform_rand(rocal_proto::Parameter *parameter, const Argument &o auto param_core = extract_param_core(op_arg); auto uniform_param = dynamic_cast *>(param_core); if (!uniform_param) { - THROW("Failed to cast parameter '" + op_arg.arg_name + "' to UniformRand type"); + THROW("Failed to cast parameter '" + op_arg.arg_name + "' to UniformRand type."); } auto uniform_range = uniform_param->get_start_and_end(); add_param_value(parameter, uniform_range.first); @@ -105,7 +105,7 @@ void serialize_custom_rand(rocal_proto::Parameter *parameter, const Argument &op auto param_core = extract_param_core(op_arg); auto random_param = dynamic_cast *>(param_core); if (!random_param) { - THROW("Failed to cast parameter '" + op_arg.arg_name + "' to CustomRand type"); + THROW("Failed to cast parameter '" + op_arg.arg_name + "' to CustomRand type."); } // Add values auto values_vec = random_param->get_values(); @@ -161,7 +161,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& serialize_parameter_to_protobuf(param, op_arg); } else if (op_arg.type_name == "enum") { if (op_arg.values.empty()) { - THROW("Enum argument " + op_arg.arg_name + " has no values"); + THROW("Enum argument " + op_arg.arg_name + " has no values."); } rocal_proto::EnumType* enum_arg = arg->mutable_enum_value(); enum_arg->set_name(op_arg.sub_type_name); @@ -180,7 +180,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& || op_arg.type_name == "map_string") { static_cast(arg->add_string_vectors()); } else { - THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); + THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name + "."); } } else { if (op_arg.type_name == "int" || op_arg.type_name == "unsigned" || op_arg.type_name == "size_t") { @@ -207,7 +207,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& vec->add_values(std::any_cast(v)); } } else { - THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name); + THROW("Vector type not supported for Argument " + op_arg.arg_name + " with type " + op_arg.type_name + "."); } } } else { @@ -229,7 +229,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& } else if (op_arg.type_name == "size_t") { arg->add_uints(std::any_cast(v)); } else { - THROW("Invalid type specified for the Argument " + op_arg.arg_name); + THROW("Invalid type specified for the Argument " + op_arg.arg_name + "."); } } } From 25066851ffe4768a0543fd0ddc4adc10ccc5ba94 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 16 Dec 2025 03:48:59 -0600 Subject: [PATCH 107/118] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 719eb1e17..e75398a52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Full documentation for rocLibrary is available at [https://rocm.docs.amd.com/pro ### Added * `PipelineSerializer` class to implement pipeline serialization functionality in rocAL. * Serialization test to validate pipeline serialization functionality. +* Python support and example to test serialization ### Changes * Adds new public APIs rocalSerialize() and rocalGetSerializedString() for serializing pipelines. From 8b03b7853153d5c08e4bf74581394f5b67d49834 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 16 Dec 2025 04:19:23 -0600 Subject: [PATCH 108/118] Fix opencv include in serialize test --- .../serialization_test/serialization_test.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index aa038a318..792832d42 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -30,15 +30,17 @@ THE SOFTWARE. #include #include "rocal_api.h" - -#ifdef USE_OPENCV_4 -#include -#include -#include -#else -#include -#include -#include +#include "opencv2/opencv.hpp" +using namespace cv; + +#if USE_OPENCV_4 +#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR +#define CV_BGR2GRAY COLOR_BGR2GRAY +#define CV_GRAY2RGB COLOR_GRAY2RGB +#define CV_RGB2BGR COLOR_RGB2BGR +#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX +#define CV_FILLED FILLED +#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE #endif int main(int argc, const char **argv) { From a1b32bf56c31d22987126ba5cbe01bdc82dd3c63 Mon Sep 17 00:00:00 2001 From: Fiona-MCW <70996026+fiona-gladwin@users.noreply.github.com> Date: Fri, 19 Dec 2025 11:53:23 +0530 Subject: [PATCH 109/118] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rocAL/source/pipeline/pipeline_serializer.cpp | 2 +- tests/cpp_api/serialization_test/serialization_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rocAL/source/pipeline/pipeline_serializer.cpp b/rocAL/source/pipeline/pipeline_serializer.cpp index 11571adcc..a9783029c 100644 --- a/rocAL/source/pipeline/pipeline_serializer.cpp +++ b/rocAL/source/pipeline/pipeline_serializer.cpp @@ -161,7 +161,7 @@ void PipelineSerializer::serialize_pipeop_arguments(const std::vector& serialize_parameter_to_protobuf(param, op_arg); } else if (op_arg.type_name == "enum") { if (op_arg.values.empty()) { - THROW("Enum argument " + op_arg.arg_name + " has no values."); + THROW("Enum argument '" + op_arg.arg_name + "' requires at least one value."); } rocal_proto::EnumType* enum_arg = arg->mutable_enum_value(); enum_arg->set_name(op_arg.sub_type_name); diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index aa038a318..f8b1b9c88 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -51,7 +51,7 @@ int main(int argc, const char **argv) { int argIdx = 1; const char *folderPath = argv[argIdx++]; - bool processing_device = 0; + int processing_device = 0; if (argc > argIdx) processing_device = atoi(argv[argIdx++]); From 9ef6fb7b62b7f527f715deddc311c09bdf5c664e Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Dec 2025 00:34:09 -0600 Subject: [PATCH 110/118] Remove OpenCV 3 usage in serialization test --- tests/cpp_api/serialization_test/CMakeLists.txt | 9 ++------- tests/cpp_api/serialization_test/serialization_test.cpp | 6 ------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/tests/cpp_api/serialization_test/CMakeLists.txt b/tests/cpp_api/serialization_test/CMakeLists.txt index 76c145694..8dfccdff2 100644 --- a/tests/cpp_api/serialization_test/CMakeLists.txt +++ b/tests/cpp_api/serialization_test/CMakeLists.txt @@ -54,17 +54,12 @@ file(GLOB My_Source_Files ./*.cpp) add_executable(${PROJECT_NAME} ${My_Source_Files}) # OpenCV configuration -if(${OpenCV_VERSION_MAJOR} EQUAL 3 OR ${OpenCV_VERSION_MAJOR} EQUAL 4) +if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 4) message("-- OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Supported") include_directories(${OpenCV_INCLUDE_DIRS}) target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) - if(${OpenCV_VERSION_MAJOR} EQUAL 4) - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=1) - else() - target_compile_definitions(${PROJECT_NAME} PUBLIC USE_OPENCV_4=0) - endif() else() - message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X Not Supported") + message(FATAL_ERROR "OpenCV Found -- Version-${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.X is not supported. OpenCV 4.0 or higher is required.") endif() # Compiler flags diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 792832d42..f0901ce85 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -33,7 +33,6 @@ THE SOFTWARE. #include "opencv2/opencv.hpp" using namespace cv; -#if USE_OPENCV_4 #define CV_LOAD_IMAGE_COLOR IMREAD_COLOR #define CV_BGR2GRAY COLOR_BGR2GRAY #define CV_GRAY2RGB COLOR_GRAY2RGB @@ -41,7 +40,6 @@ using namespace cv; #define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX #define CV_FILLED FILLED #define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE -#endif int main(int argc, const char **argv) { // check command-line usage @@ -206,11 +204,7 @@ int main(int argc, const char **argv) { out_filename = std::string(outName) + std::to_string(iter) + ".png"; // in case the user specifies non png filename if (color_format == RocalImageColor::ROCAL_COLOR_RGB24) { -#ifdef USE_OPENCV_4 cv::cvtColor(mat_output, mat_color, cv::COLOR_RGB2BGR); -#else - cv::cvtColor(mat_output, mat_color, CV_RGB2BGR); -#endif cv::imwrite(out_filename, mat_color, compression_params); } else { cv::imwrite(out_filename, mat_output, compression_params); From de3ed2ebbcc3f62c1e2c391c2e20c19c08582879 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 23 Dec 2025 00:37:41 -0600 Subject: [PATCH 111/118] Update README with prerequisites --- tests/cpp_api/serialization_test/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/cpp_api/serialization_test/README.md b/tests/cpp_api/serialization_test/README.md index 66ef86699..733f7fee4 100644 --- a/tests/cpp_api/serialization_test/README.md +++ b/tests/cpp_api/serialization_test/README.md @@ -13,6 +13,13 @@ The test validates the `rocalSerialize` and `rocalGetSerializedString` APIs by: 3. Retrieving and printing the serialized pipeline string 4. Running a few iterations to verify the pipeline works correctly +## Pre-requisites + +* Ubuntu Linux, version `22.04` or later +* rocAL library +* [OpenCV 4.0+](https://github.com/opencv/opencv/releases/tag/4.0.0) +* ROCm Performance Primitives (RPP) + ## Building ```bash From 959b6e7b80f3bca97dc2e78088af3fc81ba32d26 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Sun, 4 Jan 2026 23:33:07 -0600 Subject: [PATCH 112/118] Remove Opencv4 definitions --- tests/cpp_api/serialization_test/serialization_test.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index f0901ce85..cdf9b73bc 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -33,14 +33,6 @@ THE SOFTWARE. #include "opencv2/opencv.hpp" using namespace cv; -#define CV_LOAD_IMAGE_COLOR IMREAD_COLOR -#define CV_BGR2GRAY COLOR_BGR2GRAY -#define CV_GRAY2RGB COLOR_GRAY2RGB -#define CV_RGB2BGR COLOR_RGB2BGR -#define CV_FONT_HERSHEY_SIMPLEX FONT_HERSHEY_SIMPLEX -#define CV_FILLED FILLED -#define CV_WINDOW_AUTOSIZE WINDOW_AUTOSIZE - int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; From 6d3d6b97d97031487b8cc731b4f493ac3cc808d4 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 6 Jan 2026 04:55:26 -0600 Subject: [PATCH 113/118] Minor changes --- tests/cpp_api/serialization_test/CMakeLists.txt | 4 ++-- tests/cpp_api/serialization_test/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cpp_api/serialization_test/CMakeLists.txt b/tests/cpp_api/serialization_test/CMakeLists.txt index 8dfccdff2..6f637f8aa 100644 --- a/tests/cpp_api/serialization_test/CMakeLists.txt +++ b/tests/cpp_api/serialization_test/CMakeLists.txt @@ -50,8 +50,8 @@ include_directories(${ROCM_PATH}/include ${ROCM_PATH}/include/rocal) link_directories(${ROCM_PATH}/lib) # Source files -file(GLOB My_Source_Files ./*.cpp) -add_executable(${PROJECT_NAME} ${My_Source_Files}) +file(GLOB Source_Files ./*.cpp) +add_executable(${PROJECT_NAME} ${Source_Files}) # OpenCV configuration if(${OpenCV_VERSION_MAJOR} GREATER_EQUAL 4) diff --git a/tests/cpp_api/serialization_test/README.md b/tests/cpp_api/serialization_test/README.md index 733f7fee4..ef9c45d53 100644 --- a/tests/cpp_api/serialization_test/README.md +++ b/tests/cpp_api/serialization_test/README.md @@ -18,7 +18,7 @@ The test validates the `rocalSerialize` and `rocalGetSerializedString` APIs by: * Ubuntu Linux, version `22.04` or later * rocAL library * [OpenCV 4.0+](https://github.com/opencv/opencv/releases/tag/4.0.0) -* ROCm Performance Primitives (RPP) +* ROCm Performance Primitives ([RPP](https://github.com/ROCm/rpp)) ## Building From 4ffff8e66d9743b0b650ffaf7ea3815340be4e9f Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 6 Jan 2026 05:01:01 -0600 Subject: [PATCH 114/118] Remove extra lines --- .../serialization_test/serialization_test.cpp | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index cdf9b73bc..12d2de6af 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -50,7 +50,6 @@ int main(int argc, const char **argv) { const int inputBatchSize = 2; RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB24; - std::cout << ">>> Running serialization test on " << (processing_device ? "GPU" : "CPU") << std::endl; // Create rocAL context @@ -64,26 +63,20 @@ int main(int argc, const char **argv) { } /*>>>>>>>>>>>>>>>>>>> Graph description <<<<<<<<<<<<<<<<<<<*/ - // Create JPEG file source RocalTensor decoded_output = rocalJpegFileSource(handle, folderPath, color_format, 1, false, false); - if (rocalGetStatus(handle) != ROCAL_OK) { std::cout << "JPEG source could not initialize : " << rocalGetErrorMessage(handle) << std::endl; return -1; } - // Create label reader rocalCreateLabelReader(handle, folderPath); - if (rocalGetStatus(handle) != ROCAL_OK) { std::cout << "Label reader could not initialize : " << rocalGetErrorMessage(handle) << std::endl; return -1; } - // Add brightness augmentation (mark as output) RocalTensor brightness_output = rocalBrightness(handle, decoded_output, true); - if (rocalGetStatus(handle) != ROCAL_OK) { std::cout << "Brightness augmentation could not initialize : " << rocalGetErrorMessage(handle) << std::endl; return -1; @@ -94,45 +87,37 @@ int main(int argc, const char **argv) { std::cout << "Could not verify the augmentation graph" << std::endl; return -1; } - std::cout << "Pipeline created successfully!" << std::endl; std::cout << "Augmented copies count: " << rocalGetAugmentationBranchCount(handle) << std::endl; std::cout << "Output dimensions: " << rocalGetOutputWidth(handle) << "x" << rocalGetOutputHeight(handle) << std::endl; /*>>>>>>>>>>>>>>>>>>> Serialization Test <<<<<<<<<<<<<<<<<<<*/ - std::cout << "\n=== Testing Pipeline Serialization ===" << std::endl; // Get the size of the serialized string size_t serialized_string_size = 0; RocalStatus serialize_status = rocalSerialize(handle, &serialized_string_size); - if (serialize_status != ROCAL_OK) { std::cout << "Failed to serialize pipeline: " << rocalGetErrorMessage(handle) << std::endl; rocalRelease(handle); return -1; } - std::cout << "Serialized string size: " << serialized_string_size << " bytes" << std::endl; - + // Allocate buffer for the serialized string std::string serialized_pipe_string(serialized_string_size, '\0'); - // Get the actual serialized string RocalStatus get_string_status = rocalGetSerializedString(handle, serialized_pipe_string.data()); - if (get_string_status != ROCAL_OK) { std::cout << "Failed to get serialized string: " << rocalGetErrorMessage(handle) << std::endl; rocalRelease(handle); return -1; } - std::cout << "\n=== Serialized Pipeline String ===" << std::endl; std::cout << serialized_pipe_string << std::endl; std::cout << "=== End of Serialized String ===" << std::endl; /*>>>>>>>>>>>>>>>>>>> Test Pipeline Execution <<<<<<<<<<<<<<<<<<<*/ - std::cout << "\n=== Testing Pipeline Execution ===" << std::endl; std::cout << "Available images: " << rocalGetRemainingImages(handle) << std::endl; @@ -141,7 +126,6 @@ int main(int argc, const char **argv) { int ImageNameLen[inputBatchSize]; std::vector names; names.resize(inputBatchSize); - /*>>>>>>>>>>>>>>>>>>> Display using OpenCV <<<<<<<<<<<<<<<<<*/ int h = rocalGetAugmentationBranchCount(handle) * rocalGetOutputHeight(handle) * inputBatchSize; int w = rocalGetOutputWidth(handle); @@ -168,13 +152,11 @@ int main(int argc, const char **argv) { // Get labels RocalTensorList labels = rocalGetImageLabels(handle); - // Get image names unsigned imagename_size = rocalGetImageNameLen(handle, ImageNameLen); std::vector imageNames(imagename_size); rocalGetImageName(handle, imageNames.data()); std::string imageNamesStr(imageNames.data()); - int pos = 0; int *labels_buffer = reinterpret_cast(labels->at(0)->buffer()); for (int i = 0; i < inputBatchSize; i++) { @@ -185,11 +167,9 @@ int main(int argc, const char **argv) { // Copy Image data from handle rocalCopyToOutput(handle, mat_input.data, h * w * p); - std::vector compression_params; compression_params.push_back(cv::IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); - mat_input.copyTo(mat_output(cv::Rect(col_counter * w, 0, w, h))); std::string out_filename = std::string(outName) + ".png"; // in case the user specifies non png filename if (display_all) @@ -203,11 +183,8 @@ int main(int argc, const char **argv) { } col_counter = (col_counter + 1) % number_of_cols; } - + std::cout << "\n=== Serialization Test Completed Successfully ===" << std::endl; - - // Clean up rocalRelease(handle); - return 0; } From f821ce650f58590bce3ae81a12e9f9c32279cb8d Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 6 Jan 2026 05:35:20 -0600 Subject: [PATCH 115/118] Minor change --- .../cpp_api/serialization_test/serialization_test.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 12d2de6af..3086f69d1 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -37,24 +37,23 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - std::cout << "Usage: serialization_test \n"; + std::cout << "Usage: serialization_test \n"; return -1; } int argIdx = 1; const char *folderPath = argv[argIdx++]; - bool processing_device = 0; + bool use_gpu = false; if (argc > argIdx) - processing_device = atoi(argv[argIdx++]); + use_gpu = (atoi(argv[argIdx++]) == 1); const int inputBatchSize = 2; RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB24; - std::cout << ">>> Running serialization test on " << (processing_device ? "GPU" : "CPU") << std::endl; - + std::cout << ">>> Running serialization test on " << (use_gpu ? "GPU" : "CPU") << std::endl; // Create rocAL context auto handle = rocalCreate(inputBatchSize, - processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, + use_gpu ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); if (rocalGetStatus(handle) != ROCAL_OK) { From aacecc2145267a40f72d384330f1d42f3a068baf Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 6 Jan 2026 05:43:09 -0600 Subject: [PATCH 116/118] Revert "Minor change" This reverts commit f821ce650f58590bce3ae81a12e9f9c32279cb8d. --- .../cpp_api/serialization_test/serialization_test.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 3086f69d1..12d2de6af 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -37,23 +37,24 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - std::cout << "Usage: serialization_test \n"; + std::cout << "Usage: serialization_test \n"; return -1; } int argIdx = 1; const char *folderPath = argv[argIdx++]; - bool use_gpu = false; + bool processing_device = 0; if (argc > argIdx) - use_gpu = (atoi(argv[argIdx++]) == 1); + processing_device = atoi(argv[argIdx++]); const int inputBatchSize = 2; RocalImageColor color_format = RocalImageColor::ROCAL_COLOR_RGB24; - std::cout << ">>> Running serialization test on " << (use_gpu ? "GPU" : "CPU") << std::endl; + std::cout << ">>> Running serialization test on " << (processing_device ? "GPU" : "CPU") << std::endl; + // Create rocAL context auto handle = rocalCreate(inputBatchSize, - use_gpu ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, + processing_device ? RocalProcessMode::ROCAL_PROCESS_GPU : RocalProcessMode::ROCAL_PROCESS_CPU, 0, 1); if (rocalGetStatus(handle) != ROCAL_OK) { From 33fbabb5794ffc4f4e0295c3e858a9d47eecd975 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 6 Jan 2026 05:43:55 -0600 Subject: [PATCH 117/118] Minor change --- tests/cpp_api/serialization_test/serialization_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cpp_api/serialization_test/serialization_test.cpp b/tests/cpp_api/serialization_test/serialization_test.cpp index 12d2de6af..07fd2c6a3 100644 --- a/tests/cpp_api/serialization_test/serialization_test.cpp +++ b/tests/cpp_api/serialization_test/serialization_test.cpp @@ -37,13 +37,13 @@ int main(int argc, const char **argv) { // check command-line usage const int MIN_ARG_COUNT = 2; if (argc < MIN_ARG_COUNT) { - std::cout << "Usage: serialization_test \n"; + std::cout << "Usage: serialization_test \n"; return -1; } int argIdx = 1; const char *folderPath = argv[argIdx++]; - bool processing_device = 0; + int processing_device = 0; if (argc > argIdx) processing_device = atoi(argv[argIdx++]); From 74a346aca97d85bf89c9f0134de7c0f79bdc3058 Mon Sep 17 00:00:00 2001 From: fiona-gladwin Date: Tue, 6 Jan 2026 05:46:20 -0600 Subject: [PATCH 118/118] Minor change --- tests/python_api/pipeline_serialize_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/python_api/pipeline_serialize_test.py b/tests/python_api/pipeline_serialize_test.py index 5dfd39a60..d8306f7ee 100644 --- a/tests/python_api/pipeline_serialize_test.py +++ b/tests/python_api/pipeline_serialize_test.py @@ -123,7 +123,7 @@ def test_serialization(data_path, rocal_cpu=True, batch_size=2): print(preview_text) if len(serialized_string) > 500: print("... (truncated)") - except: + except Exception: # If binary, show hex representation print("Binary content (hex preview):") print(serialized_string[:100].hex()) @@ -178,7 +178,7 @@ def main(): # Parse arguments data_path = sys.argv[1] - rocal_cpu = (sys.argv[2].lower() == "cpu") if len(sys.argv) > 2 else True + rocal_cpu = (sys.argv[2].lower() == "cpu") if len(sys.argv) > 2 else True batch_size = int(sys.argv[3]) if len(sys.argv) > 3 else 2 # Validate data path