Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIFAR10 dataloader changes #7

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions rocAL/include/api/rocal_api_augmentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,31 @@ extern "C" RocalTensor ROCAL_API_CALL rocalCropResize(RocalContext context, Roca
RocalTensorLayout output_layout = ROCAL_NONE,
RocalTensorOutputType output_datatype = ROCAL_UINT8);

/*! \brief Fused function which perrforms crop and resize on images.
* \ingroup group_rocal_augmentations
* \note Accepts U8 and RGB24 input.
* \param [in] context Rocal context
* \param [in] input Input Rocal Tensor
* \param [in] dest_width output width
* \param [in] dest_height output height
* \param [in] is_output True: the output image is needed by user and will be copied to output buffers using the data transfer API calls. False: the output image is just an intermediate image, user is not interested in using it directly. This option allows certain optimizations to be achieved.
* \param [in] area Target area for the crop
* \param [in] aspect_ratio specifies the aspect ratio of the cropped region
* \param [in] x_center_drift Horizontal shift of the crop center from its original position in the input image
* \param [in] y_center_drift Vertical shift of the crop center from its original position in the input image
* \param [in] output_layout the layout of the output tensor
* \param [in] output_datatype the data type of the output tensor
* \return RocalTensor
*/
extern "C" RocalTensor ROCAL_API_CALL rocalRandomResizedCrop(RocalContext context, RocalTensor input,
unsigned dest_width, unsigned dest_height,
bool is_output,
std::vector<float>& area_factor,
std::vector<float>& aspect_ratio,
RocalResizeInterpolationType interpolation_type,
RocalTensorLayout output_layout = ROCAL_NONE,
RocalTensorOutputType output_datatype = ROCAL_UINT8);

/*! \brief Fused function which perrforms crop and resize on images with fixed crop coordinates.
* \ingroup group_rocal_augmentations
* \note Accepts U8 and RGB24 input.
Expand Down
23 changes: 23 additions & 0 deletions rocAL/include/api/rocal_api_data_loaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,29 @@ extern "C" RocalTensor ROCAL_API_CALL rocalRawCIFAR10Source(RocalContext context
unsigned out_width, unsigned out_height, const char* filename_prefix = "",
bool loop = false);

/*! \brief Creates CIFAR10 raw data reader and loader. It allocates the resources and objects required to read raw data stored on the file systems.
* \ingroup group_rocal_data_loaders
* \param [in] context Rocal context
* \param [in] source_path A NULL terminated char string pointing to the location on the disk
* \param [in] rocal_color_format The color format the images will be decoded to.
* \param [in] is_output Determines if the user wants the loaded images to be part of the output or not.
* \param [in] out_width output width
* \param [in] out_height output_height
* \param [in] filename_prefix if set loader will only load files with the given prefix name
* \param [in] rocal_sharding_info The members of RocalShardingInfo determines how the data is distributed among the shards and how the last batch is processed by the pipeline.
* \return Reference to the output tensor
*/
extern "C" RocalTensor ROCAL_API_CALL rocalRawCIFAR10SourceSingleShard(RocalContext context,
const char* source_path,
RocalImageColor color_format,
unsigned shard_id,
unsigned shard_count,
bool is_output,
bool shuffle,
bool loop,
unsigned out_width, unsigned out_height, const char* filename_prefix = "",
RocalShardingInfo rocal_sharding_info = RocalShardingInfo());

/*! \brief reset Loaders
* \ingroup group_rocal_data_loaders
* \param [in] context Rocal Context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,36 @@ class CropResizeNode : public CropNode {
CropResizeNode(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs);
CropResizeNode() = delete;
void init(float area, float aspect_ratio, float x_center_drift, float y_center_drift);
void init(std::vector<float>& area_factor, std::vector<float>& aspect_ratio,
RocalResizeInterpolationType interpolation_type = RocalResizeInterpolationType::ROCAL_LINEAR_INTERPOLATION);
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);
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<CropParam> get_crop_param() { return _is_random_crop ? std::static_pointer_cast<CropParam>(_crop_param) : std::static_pointer_cast<CropParam>(_crop_fixed_param); }
std::shared_ptr<CropParam> get_crop_param() {
if(_is_random_crop) {
if (_is_random_decode_crop) {
return std::static_pointer_cast<CropParam>(_crop_dec_param);
} else {
return std::static_pointer_cast<CropParam>(_crop_param);
}
} else {
return std::static_pointer_cast<CropParam>(_crop_fixed_param);
}
}

protected:
void create_node() override;
void update_node() override;

private:
std::shared_ptr<RocalRandomCropParam> _crop_param; // For random crop generation
std::shared_ptr<RocalRandomCropDecParam> _crop_dec_param; // For random decode crop generation
std::shared_ptr<RocalCropParam> _crop_fixed_param; // For fixed crop generation
vx_array _dst_roi_width, _dst_roi_height;
int _interpolation_type = 1; // Linear interpolation by default
bool _is_random_crop = true;
bool _is_random_decode_crop = false;
int _num_attempts = 100;
};
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@ THE SOFTWARE.
#include "readers/image/reader_factory.h"
#include "pipeline/timing_debug.h"

class CIFAR10DataLoader : public LoaderModule {
class CIFAR10Loader : public LoaderModule {
public:
explicit CIFAR10DataLoader(void *dev_resources);
~CIFAR10DataLoader() override;
explicit CIFAR10Loader(void *dev_resources);
~CIFAR10Loader() override;
LoaderModuleStatus load_next() override;
void initialize(ReaderConfig reader_cfg, DecoderConfig decoder_cfg, RocalMemType mem_type, unsigned batch_size, bool keep_orig_size = true) override;
void set_output(Tensor *output_tensor) override;
void set_random_bbox_data_reader(std::shared_ptr<RandomBBoxCrop_MetaDataReader> randombboxcrop_meta_data_reader) override;
size_t remaining_count() override;
void reset() override;
void start_loading() override;
void set_gpu_device_id(int device_id);
std::vector<std::string> get_id() override;
DecodedDataInfo get_decode_data_info() override;
CropImageInfo get_crop_image_info() override;
Expand All @@ -47,8 +48,11 @@ class CIFAR10DataLoader : public LoaderModule {
void shut_down() override;
std::vector<std::vector<float>> &get_batch_random_bbox_crop_coords();
void set_batch_random_bbox_crop_coords(std::vector<std::vector<float>> batch_crop_coords);
void feed_external_input(const std::vector<std::string>& input_images_names, const std::vector<unsigned char *>& input_buffer,
const std::vector<ROIxywh>& roi_xywh, unsigned int max_width, unsigned int max_height, unsigned int channels, ExternalSourceFileMode mode, bool eos) override {}
void feed_external_input(const std::vector<std::string>& input_images_names, const std::vector<unsigned char*>& input_buffer,
const std::vector<ROIxywh>& roi_xywh, unsigned int max_width, unsigned int max_height, unsigned int channels, ExternalSourceFileMode mode, bool eos) override {
THROW("external source reader is not supported for numpy loader")
};
size_t last_batch_padded_size() override;

private:
void increment_loader_idx();
Expand Down Expand Up @@ -77,7 +81,9 @@ class CIFAR10DataLoader : public LoaderModule {
void fast_forward_through_empty_loaders();
bool _is_initialized;
bool _stopped = false;
bool _loop; //<! If true the reader will wrap around at the end of the media (files/images/...) and wouldn't stop
bool _loop;
int _device_id;
//<! If true the reader will wrap around at the end of the media (files/images/...) and wouldn't stop
size_t _image_counter = 0; //!< How many images have been loaded already
size_t _remaining_image_count; //!< How many images are there yet to be loaded
Tensor *_output_tensor;
Expand Down
4 changes: 2 additions & 2 deletions rocAL/include/loaders/image/node_cifar10_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ THE SOFTWARE.
*/

#pragma once
#include "cifar10_data_loader.h"
#include "cifar10_loader.h"
#include "pipeline/graph.h"
#include "pipeline/node.h"

Expand All @@ -48,5 +48,5 @@ class Cifar10LoaderNode : public Node {
void update_node() override{};

private:
std::shared_ptr<CIFAR10DataLoader> _loader_module = nullptr;
std::shared_ptr<CIFAR10Loader> _loader_module = nullptr;
};
49 changes: 49 additions & 0 deletions rocAL/include/loaders/image/node_cifar10_loader_single_shard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Copyright (c) 2024 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 "cifar10_loader.h"
#include "pipeline/graph.h"
#include "pipeline/node.h"

class CIFAR10LoaderSingleShardNode : public Node {
public:
CIFAR10LoaderSingleShardNode(Tensor *output, void *device_resources);
~CIFAR10LoaderSingleShardNode() override;

///
/// \param shard_id shard id from user
/// \param shard_count shard count from user
/// \param source_path Defines the path that includes the image dataset
/// \param load_batch_count Defines the quantum count of the images to be loaded. It's usually equal to the user's batch size.
/// The loader will repeat images if necessary to be able to have images in multiples of the load_batch_count,
/// for example if there are 10 images in the dataset and load_batch_count is 3, the loader repeats 2 images as if there are 12 images available.
void init(unsigned shard_id, unsigned shard_count, const std::string &source_path, StorageType storage_type, bool shuffle, bool loop, size_t load_batch_count, RocalMemType mem_type, const std::string &file_prefix, const ShardingInfo& sharding_info = ShardingInfo());
std::shared_ptr<LoaderModule> get_loader_module();

protected:
void create_node() override {};
void update_node() override {};

private:
std::shared_ptr<CIFAR10Loader> _loader_module = nullptr;
};
2 changes: 1 addition & 1 deletion rocAL/include/parameters/parameter_crop.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ THE SOFTWARE.
*/

#pragma once
#include <VX/vx_types.h>
#include "pipeline/graph.h"

#include "parameters/parameter_factory.h"
enum class RocalCropType {
Expand Down
1 change: 1 addition & 0 deletions rocAL/include/parameters/parameter_crop_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ THE SOFTWARE.
#pragma once
#include "parameters/parameter_rocal_crop.h"
#include "parameters/parameter_random_crop.h"
#include "parameters/parameter_random_crop_decoder.h"

//std::shared_ptr<CropParam> create_crop(CroopConfig config);
17 changes: 12 additions & 5 deletions rocAL/include/parameters/parameter_random_crop_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ THE SOFTWARE.
#pragma once
#include <random>
#include <thread>

#include "parameters/parameter_factory.h"
#include "parameters/parameter_crop.h"

struct CropWindow {
unsigned x, y, H, W;
Expand All @@ -42,16 +41,24 @@ typedef std::vector<size_t> Shape;
using AspectRatioRange = std::pair<float, float>;
using AreaRange = std::pair<float, float>;

class RocalRandomCropDecParam {
class RocalRandomCropDecParam : public CropParam {
public:
explicit RocalRandomCropDecParam(
RocalRandomCropDecParam(
AspectRatioRange aspect_ratio_range = {3.0f / 4, 4.0f / 3},
AreaRange area_range = {0.08, 1},
int64_t seed = time(0),
int num_attempts = 10,
int batch_size = 256);
int batch_size = 256) : CropParam(batch_size) {
_aspect_ratio_range = aspect_ratio_range;
_aspect_ratio_log_dis = std::uniform_real_distribution<float>(std::log(aspect_ratio_range.first), std::log(aspect_ratio_range.second));
_area_dis = std::uniform_real_distribution<float>(area_range.first, area_range.second);
_num_attempts = num_attempts;
_batch_size = batch_size;
_seeds.resize(_batch_size);
}
CropWindow generate_crop_window(const Shape& shape, const int instance);
void generate_random_seeds();
void update_array() override;

private:
CropWindow generate_crop_window_implementation(const Shape& shape);
Expand Down
18 changes: 18 additions & 0 deletions rocAL/include/pipeline/master_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ THE SOFTWARE.
#include "meta_data/meta_data_reader.h"
#include "pipeline/node.h"
#include "loaders/image/node_cifar10_loader.h"
#include "loaders/image/node_cifar10_loader_single_shard.h"
#include "loaders/image/node_fused_jpeg_crop.h"
#include "loaders/image/node_fused_jpeg_crop_single_shard.h"
#include "loaders/image/node_image_loader.h"
Expand Down Expand Up @@ -362,6 +363,23 @@ inline std::shared_ptr<Cifar10LoaderNode> MasterGraph::add_node(const std::vecto
return node;
}

template<> inline std::shared_ptr<CIFAR10LoaderSingleShardNode> MasterGraph::add_node(const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs) {
if(_loader_module)
THROW("A loader already exists, cannot have more than one loader")
#if ENABLE_HIP || ENABLE_OPENCL
auto node = std::make_shared<CIFAR10LoaderSingleShardNode>(outputs[0], (void *)_device.resources());
#else
auto node = std::make_shared<CIFAR10LoaderSingleShardNode>(outputs[0], nullptr);
#endif
_loader_module = node->get_loader_module();
_loader_module->set_prefetch_queue_depth(_prefetch_queue_depth);
_root_nodes.push_back(node);
for(auto& output: outputs)
_tensor_map.insert(make_pair(output, node));

return node;
}

#ifdef ROCAL_VIDEO
/*
* Explicit specialization for VideoLoaderNode
Expand Down
44 changes: 44 additions & 0 deletions rocAL/source/api/rocal_api_augmentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,50 @@ rocalCropResize(
return output;
}

RocalTensor ROCAL_API_CALL
rocalRandomResizedCrop(
RocalContext p_context,
RocalTensor p_input,
unsigned dest_width, unsigned dest_height,
bool is_output,
std::vector<float>& area_factor,
std::vector<float>& aspect_ratio,
RocalResizeInterpolationType interpolation_type,
RocalTensorLayout output_layout,
RocalTensorOutputType output_datatype) {
Tensor* output = nullptr;
if ((p_context == nullptr) || (p_input == nullptr)) {
ERR("Invalid ROCAL context or invalid input tensor")
return output;
}

auto context = static_cast<Context*>(p_context);
auto input = static_cast<Tensor*>(p_input);
try {
if (dest_width == 0 || dest_height == 0)
THROW("rocalRandomResizedCrop node needs to receive non-zero destination dimensions")

RocalTensorlayout op_tensor_layout = static_cast<RocalTensorlayout>(output_layout);
RocalTensorDataType op_tensor_datatype = static_cast<RocalTensorDataType>(output_datatype);
TensorInfo output_info = input->info();
output_info.set_data_type(op_tensor_datatype);

// For the crop resize node, user can create an image with a different width and height
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<CropResizeNode> random_resize_crop_node = context->master_graph->add_node<CropResizeNode>({input}, {output});
random_resize_crop_node->init(area_factor, aspect_ratio, interpolation_type);
if (context->master_graph->meta_data_graph())
context->master_graph->meta_add_node<CropResizeMetaNode, CropResizeNode>(random_resize_crop_node);
} catch (const std::exception& e) {
context->capture_error(e.what());
ERR(e.what())
}
return output;
}

RocalTensor ROCAL_API_CALL
rocalCropResizeFixed(
RocalContext p_context,
Expand Down
Loading