("Could not find TensorsData handle with given id: %d", tensor_data_id));
return;
}
- // TODO: validate location and size - will be done in future commit
- unsigned int location[ML_TENSOR_RANK_LIMIT];
- unsigned int size[ML_TENSOR_RANK_LIMIT];
+
+ unsigned int location[ML_TENSOR_RANK_LIMIT] = {};
+ PlatformResult result =
+ util::GetLocationFromJsonArray(args.get(kLocation).get<picojson::array>(), location);
+ if (!result) {
+ LogAndReportError(result, &out);
+ return;
+ }
+
+ unsigned int dimensions[ML_TENSOR_RANK_LIMIT] = {};
+ result = tensors_data->GetTensorsInfo()->NativeGetTensorDimensions(index, dimensions);
+ if (!result) {
+ LogAndReportError(result, &out);
+ return;
+ }
+
+ unsigned int size[ML_TENSOR_RANK_LIMIT] = {};
+ result = util::GetSizeFromJsonArray(args.get(kSize).get<picojson::array>(), location, dimensions,
+ size);
+ if (!result) {
+ LogAndReportError(result, &out);
+ return;
+ }
+
TensorRawData raw_data;
- PlatformResult result = tensors_data->GetTensorRawData(index, location, size, &raw_data);
+ result = tensors_data->GetTensorRawData(index, location, size, &raw_data);
if (!result) {
LogAndReportError(result, &out);
return;
std::vector<std::uint8_t> buffer;
common::decode_binary_from_string(str_buffer, buffer);
- TensorRawData rawData{.data = buffer.data(), .size_in_bytes = buffer.size()};
- result = tensors_data->SetTensorRawData(index, location, size, rawData);
+ TensorRawData raw_data{buffer.data(), buffer.size()};
+ result = tensors_data->SetTensorRawData(index, location, size, raw_data);
if (!result) {
LogAndReportError(result, &out);
return;
unsigned int size[ML_TENSOR_RANK_LIMIT],
TensorRawData* tensor_raw_data) {
ScopeLogger("id_: %d, index: %d", id_, index);
+
if (nullptr == tensor_raw_data) {
LoggerE("Invalid tensor_raw_data");
return PlatformResult(ErrorCode::ABORT_ERR);
}
- void* data;
+
+ void* void_data;
size_t data_size;
- PlatformResult result = NativeGetTensorData(index, &data, &data_size);
+ PlatformResult result = NativeGetTensorData(index, &void_data, &data_size);
if (!result) {
return result;
}
- // TODO: add support for location and size - will be done in future commit
+ uint8_t* data = static_cast<uint8_t*>(void_data);
// Dimensions of whole tensor
unsigned int dim[ML_TENSOR_RANK_LIMIT];
+ // Dimensions of expected tensors relative to location coordiantes
+ unsigned int size_rel[ML_TENSOR_RANK_LIMIT];
+
result = tensors_info_->NativeGetTensorDimensions(index, dim);
if (!result) {
return result;
}
+ // Check if update is partial due to location change
+ bool partial = false;
for (int i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
- tensor_raw_data->shape[i] = dim[i];
+ if (location[i] >= dim[i]) {
+ // Input data starts outside of current data
+ LoggerE("Requested data location is invalid on [%d]: %u", i, location[i]);
+ return PlatformResult{ErrorCode::INVALID_VALUES_ERR, "Requested data location is invalid"};
+ } else if (location[i] != 0) {
+ partial = true;
+ }
+ }
+
+ uint8_t bytes_per_element = tensors_info_->GetBytesPerElement(index);
+ size_t data_to_be_returned_size = bytes_per_element;
+
+ // Check if data will fit in TensorData and calculate dimensions
+ // of returned part, also check if update is partial due to size change
+ for (int i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
+ size_rel[i] = location[i] + size[i];
+ if (size_rel[i] < dim[i]) {
+ partial = true;
+ } else {
+ size_rel[i] = dim[i];
+ }
+ data_to_be_returned_size *= (size_rel[i] - location[i]);
+ }
+
+ if (partial) {
+ LoggerD("Partial get of tensor data");
+ // Allocate data, it will be freed on TensorRawData destruction
+ auto new_data = std::make_unique<uint8_t[]>(data_to_be_returned_size);
+ size_t position_in_new_data = 0;
+
+ size_t delta2 = dim[1] * dim[0] * bytes_per_element;
+ size_t delta1 = dim[0] * bytes_per_element;
+
+ size_t position = location[3] * dim[2] * delta2;
+ for (unsigned int i = location[3]; i < size_rel[3]; i++) {
+ position += (location[2]) * delta2;
+ for (unsigned int j = location[2]; j < size_rel[2]; j++) {
+ position += (location[1]) * delta1;
+ for (unsigned int k = location[1]; k < size_rel[1]; k++) {
+ position += location[0] * bytes_per_element;
+ size_t length = (size_rel[0] - location[0]) * bytes_per_element;
+ mempcpy(&new_data[position_in_new_data], &data[position], length);
+ position_in_new_data += length;
+ position += (dim[0] - location[0]) * bytes_per_element;
+ }
+ position += (dim[1] - size_rel[1]) * delta1;
+ }
+ position += (dim[2] - size_rel[2]) * delta2;
+ }
+ if (position_in_new_data != data_to_be_returned_size) {
+ LoggerE("Error while copying data, expected: %zu, got: %zu", data_to_be_returned_size,
+ position_in_new_data);
+ return PlatformResult{ErrorCode::ABORT_ERR, "Internal error while fetching the data"};
+ }
+ tensor_raw_data->data = new_data.release();
+ tensor_raw_data->size_in_bytes = position_in_new_data;
+ tensor_raw_data->SetOwnership(true);
+ } else {
+ tensor_raw_data->data = data;
+ tensor_raw_data->size_in_bytes = data_size;
+ }
+
+ for (int i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
+ tensor_raw_data->shape[i] = size_rel[i] - location[i];
}
result = types::TensorTypeEnum.getName(this->GetTensorType(index), &tensor_raw_data->type_str);
return result;
}
- tensor_raw_data->data = static_cast<uint8_t*>(data);
- tensor_raw_data->size_in_bytes = data_size;
-
return PlatformResult(ErrorCode::NO_ERROR);
}
unsigned int location[] = {0, 0, 0, 0};
unsigned int size[] = {3, 2, 2, 1};
uint8_t arr_in[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 12};
+ TensorRawData raw_data_set{arr_in, 12};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_TRUE(res) << "SetTensorRawData failed";
TensorRawData raw_data_get;
- res = tensors_data->GetTensorRawData(0, location, dim, &raw_data_get);
+ unsigned int location_get[] = {0, 0, 0, 0};
+ res = tensors_data->GetTensorRawData(0, location_get, dim, &raw_data_get);
ASSERT_TRUE(res) << "GetTensorRawData failed";
unsigned int expected_dim[] = {3, 2, 2, 1};
unsigned int location[] = {0, 0, 0, 0};
unsigned int size[] = {3, 2, 1, 1};
uint8_t arr_in[] = {1, 2, 3, 4, 5, 6};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 6};
+ TensorRawData raw_data_set{arr_in, 6};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_TRUE(res) << "SetTensorRawData failed";
TensorRawData raw_data_get;
- res = tensors_data->GetTensorRawData(0, location, dim, &raw_data_get);
+ unsigned int location_get[] = {0, 0, 0, 0};
+ res = tensors_data->GetTensorRawData(0, location_get, dim, &raw_data_get);
ASSERT_TRUE(res) << "GetTensorRawData failed";
unsigned int expected_dim[] = {3, 2, 2, 1};
unsigned int location[] = {0, 0, 1, 0};
unsigned int size[] = {3, 2, 1, 1};
uint8_t arr_in[] = {1, 2, 3, 4, 5, 6};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 6};
+ TensorRawData raw_data_set{arr_in, 6};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_TRUE(res) << "SetTensorRawData failed";
TensorRawData raw_data_get;
- res = tensors_data->GetTensorRawData(0, location, dim, &raw_data_get);
+
+ unsigned int location_get[] = {0, 0, 0, 0};
+ res = tensors_data->GetTensorRawData(0, location_get, dim, &raw_data_get);
ASSERT_TRUE(res) << "GetTensorRawData failed";
unsigned int expected_dim[] = {3, 2, 2, 1};
unsigned int location[] = {1, 1, 0, 0};
unsigned int size[] = {2, 1, 1, 1};
uint8_t arr_in[] = {1, 2};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 2};
+ TensorRawData raw_data_set{arr_in, 2};
+ raw_data_set.data = arr_in;
+ raw_data_set.size_in_bytes = 2;
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_TRUE(res) << "SetTensorRawData failed";
TensorRawData raw_data_get;
- res = tensors_data->GetTensorRawData(0, location, dim, &raw_data_get);
+ unsigned int location_get[] = {0, 0, 0, 0};
+ res = tensors_data->GetTensorRawData(0, location_get, dim, &raw_data_get);
ASSERT_TRUE(res) << "GetTensorRawData failed";
unsigned int expected_dim[] = {3, 2, 2, 1};
unsigned int location[] = {1, 0, 1, 1};
unsigned int size[] = {1, 2, 1, 1};
uint8_t arr_in[] = {1, 2};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 2};
+ TensorRawData raw_data_set{arr_in, 2};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_TRUE(res) << "SetTensorRawData failed";
TensorRawData raw_data_get;
- res = tensors_data->GetTensorRawData(0, location, dim, &raw_data_get);
+ unsigned int location_get[] = {0, 0, 0, 0};
+ res = tensors_data->GetTensorRawData(0, location_get, dim, &raw_data_get);
ASSERT_TRUE(res) << "GetTensorRawData failed";
unsigned int expected_dim[] = {3, 2, 2, 2};
unsigned int location[] = {2, 1, 1, 1};
unsigned int size[] = {1, 1, 1, 1};
int arr_in[] = {-34};
- TensorRawData raw_data_set = {.data = (uint8_t*)arr_in, .size_in_bytes = 4};
+ TensorRawData raw_data_set{(uint8_t*)arr_in, 4};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_TRUE(res) << "SetTensorRawData failed";
TensorRawData raw_data_get;
- res = tensors_data->GetTensorRawData(0, location, dim, &raw_data_get);
+ unsigned int location_get[] = {0, 0, 0, 0};
+ res = tensors_data->GetTensorRawData(0, location_get, dim, &raw_data_get);
ASSERT_TRUE(res) << "GetTensorRawData failed";
unsigned int expected_dim[] = {3, 2, 2, 2};
unsigned int location[] = {4, 0, 0, 0};
unsigned int size[] = {1, 1, 1, 1};
uint8_t arr_in[1] = {};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 1};
+ TensorRawData raw_data_set{arr_in, 1};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_FALSE(res) << "SetTensorRawData should fail";
ASSERT_EQ(res.error_code(), ErrorCode::INVALID_VALUES_ERR) << "Invalid error code";
unsigned int location[] = {0, 0, 0, 0};
unsigned int size[] = {2, 1, 1, 1};
uint8_t arr_in[1] = {};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 1};
+ TensorRawData raw_data_set{arr_in, 1};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_FALSE(res) << "SetTensorRawData should fail";
ASSERT_EQ(res.error_code(), ErrorCode::INVALID_VALUES_ERR) << "Invalid error code";
unsigned int location[] = {0, 0, 0, 0};
unsigned int size[] = {1, 1, 1, 1};
uint8_t arr_in[400] = {};
- TensorRawData raw_data_set = {.data = arr_in, .size_in_bytes = 400};
+ TensorRawData raw_data_set{arr_in, 400};
PlatformResult res = tensors_data->SetTensorRawData(0, location, size, raw_data_set);
ASSERT_FALSE(res) << "SetTensorRawData should fail";
ASSERT_EQ(res.error_code(), ErrorCode::INVALID_VALUES_ERR) << "Invalid error code";