Fix benchmarking utils on RISC-V (#2130)
The generic benchmarking utilities added in PR 2125 did not compile on RISC-V due to two separate issues:
* An incorrect format specifier for int32_t on RISC-V. This is resolved by using PRId32 instead of %ld or %d.
* The fileno() is undeclared with the RISC-V toolchain, similar to how it is with the Embedded ARM toolchain. This PR resolves this by forgoing the fstat() check on file size (as this is what used fileno), and instead attempting to read the maximum number of bytes we can fit in the model buffer. We can then use feof() to verify that we read the entirety of the model, and error out if we did not. This solution also eliminates needing to worry about different file types, such as how the Xtensa simulator treats files from the host system as character devices.
BUG=2129
diff --git a/tensorflow/lite/micro/tools/benchmarking/generic_model_benchmark.cc b/tensorflow/lite/micro/tools/benchmarking/generic_model_benchmark.cc
index 1c2f4b9..c1db8fa 100644
--- a/tensorflow/lite/micro/tools/benchmarking/generic_model_benchmark.cc
+++ b/tensorflow/lite/micro/tools/benchmarking/generic_model_benchmark.cc
@@ -13,6 +13,7 @@
limitations under the License.
==============================================================================*/
+#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -76,37 +77,20 @@
}
bool ReadFile(const char* file_name, void* buffer, size_t buffer_size) {
- // Obtain the file size using fstat, or report an error if that fails.
std::unique_ptr<FILE, decltype(&fclose)> file(fopen(file_name, "rb"), fclose);
- struct stat sb;
-// For CMSIS_NN, the compilation is failing with the following error
-// 'fileno' was not declared in this scope
-// TODO(b/290988791): Investigate why fileno is not defined in arm toolchain.
-#if defined(CMSIS_NN)
- if (fstat(file.get()->_file, &sb) != 0) {
-#else
- if (fstat(fileno(file.get()), &sb) != 0) {
-#endif
- MicroPrintf("Failed to get file size of: %s\n", file_name);
+ const size_t bytes_read =
+ fread(buffer, sizeof(char), buffer_size, file.get());
+ if (ferror(file.get())) {
+ MicroPrintf("Unable to read model file: %d\n", ferror(file.get()));
return false;
}
-
- if (!buffer) {
- MicroPrintf("Malloc of buffer to hold copy of '%s' failed\n", file_name);
+ if (!feof(file.get())) {
+ MicroPrintf("Model buffer is too small for the model.\n");
return false;
}
-
- if (S_ISREG(sb.st_mode) != 0 &&
- (sb.st_size < 0 || (static_cast<size_t>(sb.st_size) > buffer_size))) {
- MicroPrintf(
- "Buffer size (%ld) to hold the model is less than required %ld.\n",
- buffer_size, sb.st_size);
- return false;
- }
-
- if (!fread(buffer, sizeof(char), sb.st_size, file.get())) {
- MicroPrintf("Unable to read the model file or the model file is empty.\n");
+ if (bytes_read == 0) {
+ MicroPrintf("No bytes read from model file.\n");
return false;
}
@@ -173,4 +157,4 @@
} // namespace
} // namespace tflite
-int main(int argc, char** argv) { return tflite::Benchmark(argv[1]); }
\ No newline at end of file
+int main(int argc, char** argv) { return tflite::Benchmark(argv[1]); }
diff --git a/tensorflow/lite/micro/tools/benchmarking/log_utils.cc b/tensorflow/lite/micro/tools/benchmarking/log_utils.cc
index 8ac4ca3..808e465 100644
--- a/tensorflow/lite/micro/tools/benchmarking/log_utils.cc
+++ b/tensorflow/lite/micro/tools/benchmarking/log_utils.cc
@@ -15,6 +15,7 @@
#include "tensorflow/lite/micro/tools/benchmarking/log_utils.h"
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
@@ -90,11 +91,7 @@
template <>
void FormatNumber<int32_t>(char* output, int32_t value) {
-#if defined(HEXAGON) || defined(CMSIS_NN)
- sprintf(output, "%ld", value); // NOLINT: sprintf required.
-#else
- sprintf(output, "%d", value); // NOLINT: sprintf required.
-#endif
+ sprintf(output, "%" PRId32, value); // NOLINT: sprintf required.
}
template <>