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

Numpy reader changes #5

Open
wants to merge 5 commits into
base: param_vx_changes
Choose a base branch
from

Conversation

SundarRajan98
Copy link
Owner

No description provided.

@SundarRajan98 SundarRajan98 self-assigned this Feb 19, 2024
@SundarRajan98 SundarRajan98 changed the base branch from develop to param_vx_changes February 19, 2024 07:16
Copy link
Collaborator

@fiona-gladwin fiona-gladwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address review comments
Change copyright in newly added files

rocAL/include/api/rocal_api_augmentation.h Outdated Show resolved Hide resolved
rocAL/include/api/rocal_api_augmentation.h Outdated Show resolved Hide resolved
@@ -1098,4 +1098,6 @@ extern "C" RocalTensor ROCAL_API_CALL rocalSSDRandomCrop(RocalContext context, R
RocalTensorLayout output_layout = ROCAL_NONE,
RocalTensorOutputType output_datatype = ROCAL_UINT8);

extern "C" RocalTensor ROCAL_API_CALL rocalSetLayout(RocalContext context, RocalTensor input,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API is to set the layout for any tensor, In that case why is it included in api_augmentations.h?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Numpy loader doesn't provide layout for the loader tensor so I'm using the set layout function to specify the layout for augmentations.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What layouts will be set for numpy reader? Where this will be called?
I think we need to rename output_layout to just layout.

rocAL/include/api/rocal_api_data_loaders.h Outdated Show resolved Hide resolved
* \param [in] context Rocal context
* \param [in] source_path A NULL terminated char string pointing to the location on the disk
* \param [in] internal_shard_count Defines the parallelism level by internally sharding the input dataset and load/decode using multiple decoder/loader instances. Using shard counts bigger than 1 improves the load/decode performance if compute resources (CPU cores) are available.
* \param [in] is_output Determines if the user wants the loaded images to be part of the output or not.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it loaded images here?
Please rephrase according to the API, applicable to the other lines of description where image is used

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The numpy arrays are 4D images but I'll rephrase this as loaded arrays

rocAL_pybind/amd/rocal/plugin/pytorch.py Outdated Show resolved Hide resolved
rocAL_pybind/amd/rocal/plugin/pytorch.py Show resolved Hide resolved
rocAL_pybind/amd/rocal/plugin/pytorch.py Show resolved Hide resolved
rocAL_pybind/amd/rocal/readers.py Outdated Show resolved Hide resolved
m.def("rocalResetLoaders", &rocalResetLoaders);
m.def("videoMetaDataReader", &rocalCreateVideoLabelReader, py::return_value_policy::reference);
// rocal_api_augmentation.h
m.def("setLayout", &rocalSetLayout,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check if this must come under augmentation.h

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dataloader APIs are used for dataset specific functions but this one seemed to be a tensor specific function which is why I added it in api_augmentations.h
@shobana-mcw to check

out_f_buffer = (float *)output_tensor_list->at(idx)->buffer();

out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size() / 4);
// convert_float_to_uchar_buffer(out_f_buffer, out_buffer, output_tensor_list->at(idx)->data_size() / 4);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code in line 793

out_f16_buffer = (half *)output_tensor_list->at(idx)->buffer();

out_buffer = (unsigned char *)malloc(output_tensor_list->at(idx)->data_size() / 2);
// convert_float_to_uchar_buffer(out_f16_buffer, out_buffer, output_tensor_list->at(idx)->data_size() / 2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the commented code

@@ -0,0 +1,48 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if the 3 top imports is necessary and remove if not needed

import amd.rocal.fn as fn
import amd.rocal.types as types
import sys
import os
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import seems unsused. Please remove it

print("+++++++++++++++++++++++++++++EPOCH+++++++++++++++++++++++++++++++++++++",epoch)
for i , [it] in enumerate(numpyIteratorPipeline):
print(it.shape)
print("************************************** i *************************************",i)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after ,

print(len(numpyIteratorPipeline))
for epoch in range(1):
print("+++++++++++++++++++++++++++++EPOCH+++++++++++++++++++++++++++++++++++++",epoch)
for i , [it] in enumerate(numpyIteratorPipeline):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it needed to be used inside sqare bracktes ?



def numpy(*inputs, file_root='', num_shards=1,
random_shuffle=False, shard_id=0, stick_to_shard=False, pad_last_batch=False):
Copy link
Collaborator

@swetha097 swetha097 Feb 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move
random_shuffle=False, shard_id=0, stick_to_shard=False, pad_last_batch=False):
to prev line

@@ -350,3 +350,15 @@ def mxnet(path, stick_to_shard=False, pad_last_batch=False):
mxnet_metadata = b.mxnetReader(
Pipeline._current_pipeline._handle, *(kwargs_pybind.values()))
return mxnet_metadata


def numpy(*inputs, file_root='', num_shards=1,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add docstring explaning each argument

@@ -29,6 +29,91 @@
import ctypes


class ROCALNumpyIterator(object):
def __init__(self, pipeline, tensor_dtype=types.FLOAT, device="cpu", device_id=0, return_roi=False):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a part of the pytorch.py ? @shobana-mcw please add comments

@@ -29,6 +29,95 @@
import amd.rocal.types as types
import ctypes

class ROCALNumpyIterator(object):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Numpy iterator seems to be added in both the generic.py and the pytorch.py.

We should think about keeping it here or just as a custom iterator in the respective example pipelines as was done for Coco Readers

@shobana-mcw Please add your comments on this

#include "numpy_data_reader.h"

#include <commons.h>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove blank lines

size_t read_size = 0;
for (unsigned d = 0; d < shapes[dim]; d++) {
read_size += copy_array_data<T>(startPtr, strides, shapes, dim + 1);
startPtr += strides[dim + 1];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change from CamelCase to snake_case

LoaderModuleStatus load_next() override;
void initialize(ReaderConfig reader_cfg, DecoderConfig decoder_cfg, RocalMemType mem_type, unsigned batch_size, bool keep_orig_size = false) override;
void set_output(Tensor* output_image) override;
void set_random_bbox_data_reader(std::shared_ptr<RandomBBoxCrop_MetaDataReader> randombboxcrop_meta_data_reader) override;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void set_random_bbox_data_reader(std::shared_ptr<RandomBBoxCrop_MetaDataReader> randombboxcrop_meta_data_reader) override { THROW("set_random_bbox_data_reader is not compatible with this implementation") };

Please change to THROW err

while ((file_counter != _batch_size) && _reader->count_items() > 0) {
auto read_ptr = data + _image_size * file_counter;
auto max_shape = _output_tensor->info().max_shape();
size_t readSize = _reader->open();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change from cameCase to snake_case

*/

#include "node_numpy_loader_single_shard.h"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this blank line

auto context = static_cast<Context*>(p_context);
try {
auto max_dimensions = evaluate_numpy_data_set(StorageType::NUMPY_DATA, DecoderType::SKIP_DECODE,
source_path);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this to prev line

try {
auto max_dimensions = evaluate_numpy_data_set(StorageType::NUMPY_DATA, DecoderType::SKIP_DECODE,
source_path);
auto dtype = max_dimensions.at(max_dimensions.size() - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does dimensions store data type ?

template <size_t N>
bool check_and_skip_string(const char*& ptr, const char (&what)[N]);
template <size_t N>
void skip_field(const char*& ptr, const char (&name)[N]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to add comments here on what this function does ?

#include "circular_buffer.h"
#include "commons.h"
#include "image_read_and_decode.h"
//
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this //

void fast_forward_through_empty_loaders();
size_t _prefetch_queue_depth;
Tensor *_output_tensor;
std::shared_ptr<RandomBBoxCrop_MetaDataReader> _randombboxcrop_meta_data_reader = nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be removed and add This doesnt the implementation for the function set_random_bbox_data_reader

* \return Reference to the output tensor
*/
extern "C" RocalTensor ROCAL_API_CALL rocalNumpyFileSource(
RocalContext p_context,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please align the argumengts

* \return Reference to the output tensor
*/
extern "C" RocalTensor rocalNumpyFileSourceSingleShard(
RocalContext p_context,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please align the arguments, refer other functions above

Copy link
Collaborator

@swetha097 swetha097 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added review comments , please address it

Copy link
Collaborator

@shobana-mcw shobana-mcw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address the review comments.
I will review the cpp files and add comments.

@@ -1098,4 +1098,6 @@ extern "C" RocalTensor ROCAL_API_CALL rocalSSDRandomCrop(RocalContext context, R
RocalTensorLayout output_layout = ROCAL_NONE,
RocalTensorOutputType output_datatype = ROCAL_UINT8);

extern "C" RocalTensor ROCAL_API_CALL rocalSetLayout(RocalContext context, RocalTensor input,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What layouts will be set for numpy reader? Where this will be called?
I think we need to rename output_layout to just layout.

*/

#pragma once
#include "graph.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this include? Check this.

/// \param internal_shard_count Defines the amount of parallelism user wants for the load and decode process to be handled internally.
/// \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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change these comments since its wrt images.

/// \param user_shard_id shard id from user
/// \param source_path Defines the path that includes the numpy array dataset
/// \param load_batch_count Defines the quantum count of the numpy arrays to be loaded. It's usually equal to the user's batch size.
/// The loader will repeat samples if necessary to be able to have samples in multiples of the load_batch_count,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change these comments since its wrt images.

LoaderModuleStatus set_cpu_sched_policy(struct sched_param sched_policy);
void set_gpu_device_id(int device_id);
std::vector<std::string> get_id() override;
decoded_image_info get_decode_image_info() override;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use this API in numpy reader?

size_t _image_size;
std::thread _load_thread;
RocalMemType _mem_type;
decoded_image_info _decoded_img_info;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address this.

@@ -41,10 +41,14 @@ enum class MaxSizeEvaluationPolicy {
class ImageSourceEvaluator {
public:
ImageSourceEvaluatorStatus create(ReaderConfig reader_cfg, DecoderConfig decoder_cfg);
ImageSourceEvaluatorStatus create(ReaderConfig reader_cfg);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we introduce another file for numpy source evaluator? Are there any common functions required?

@@ -389,3 +391,39 @@ inline std::shared_ptr<VideoLoaderSingleShardNode> MasterGraph::add_node(const s

return node;
}

template <>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comments.

@@ -162,6 +183,10 @@ class Reader {
//! Copies the data of the opened item to the buf
virtual size_t read_data(unsigned char *buf, size_t read_size) = 0;

virtual const NumpyHeaderData get_numpy_header_data() { THROW("Not Implemented") }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comments for these API.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to introduce numpy API's here?
Can we try multiple inheritance?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both APIs are needed for numpy source evaluator

@@ -2155,3 +2155,26 @@ rocalNop(
}
return output;
}

RocalTensor ROCAL_API_CALL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API should not be part of this file.

if (internal_shard_count < 1)
THROW("Shard count should be greater than or equal to one")
_loader_module->set_output(_outputs[0]);
// Set reader and decoder config accordingly for the NumpyLoaderNode
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the comments. We don't use a decoder config.

Copy link
Collaborator

@shobana-mcw shobana-mcw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the numpy related files to a new folder called numpy. It need not be under images. Need to make this change for loader and reader.

if (shard_id >= shard_count)
THROW("Shard is should be smaller than shard count")
_loader_module->set_output(_outputs[0]);
// Set reader and decoder config accordingly for the NumpyLoaderNode
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove decoder config in comments.


increment_loader_idx();

// Since loaders may have different number of images loaded, some run out earlier than other.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the comments wrt images.

}

void NumpyLoaderSharded::set_random_bbox_data_reader(std::shared_ptr<RandomBBoxCrop_MetaDataReader> randombboxcrop_meta_data_reader) {
_randombboxcrop_meta_data_reader = randombboxcrop_meta_data_reader;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address this.

@@ -0,0 +1,65 @@
/*
Copyright (c) 2019 - 2023 Advanced Micro Devices, Inc. All rights reserved.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the copyrights year.

Comment on lines +127 to +128
unsigned *tensor_shape = _roi[i].end;
tensor_shape[i] = _max_shape[i];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address this.

LOG("NumpyDataReader ShardID [" + TOSTR(_shard_id) + "] Replicated " + _folder_path + _last_file_name + " " + TOSTR((_batch_count - _in_batch_read_count)) + " times to fill the last batch")
}
if (!_file_names.empty())
LOG("NumpyDataReader ShardID [" + TOSTR(_shard_id) + "] Total of " + TOSTR(_file_names.size()) + " images loaded from " + _full_path)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the reference of image.

std::string subfolder_path = _full_path + "/" + entry_name_list[dir_count];
filesys::path pathObj(subfolder_path);
if (filesys::exists(pathObj) && filesys::is_regular_file(pathObj)) {
// ignore files with extensions .tar, .zip, .7z
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are we checking for this?

}

const RocalTensorDataType NumpyDataReader::get_numpy_dtype(const std::string& format) {
if (format == "u1") return RocalTensorDataType::UINT8;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switch case will be more readable.

@@ -0,0 +1,48 @@
from __future__ import absolute_import
from __future__ import division
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's no division operation being used in this file. Please remove it if it is not used.

import os

def main():
if len(sys.argv) < 3:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be 'if len(sys.argv) < 4' here, as you require three arguments, and argv[0] by default contains the Python script name.

numpyIteratorPipeline = ROCALNumpyIterator(pipeline, tensor_dtype=types.UINT8)
print(len(numpyIteratorPipeline))
for epoch in range(1):
print("+++++++++++++++++++++++++++++EPOCH+++++++++++++++++++++++++++++++++++++",epoch)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space before epoch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants