Loading a Model from a File (C)
The following walkthrough is a C example demonstrating how to load a model from a file.
#include "rml/RadeonML.h"
#include "rml/RadeonML_graph.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RML_CHECK(STATUS) \
do \
{ \
if (STATUS != RML_OK) \
{ \
printf("%s\n", rmlGetLastError());\
exit(EXIT_FAILURE); \
} \
} while (0)
#define CHECK(STATUS) \
do \
{ \
if (!(STATUS)) \
{ \
exit(EXIT_FAILURE); \
} \
} while (0)
#define MAX_INPUTS 1
/*
* Read input from file
* Must be free memory after caller of this function
*
* @param input_file - name of input file
* @return - string content of file
*/
void* ReadInput(const char* input_file)
{
void* buffer;
FILE* file = fopen(input_file, "rb");
CHECK(file != NULL);
printf("Reading data from file: %s\n", input_file);
fseek(file, 0, SEEK_END);
long length = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = malloc((length) * sizeof(char));
CHECK(buffer != NULL);
size_t num_read = fread(buffer, sizeof(char), length, file);
CHECK(num_read == length);
printf("Input data size: %zu\n", num_read);
fclose(file);
return buffer;
}
/*
* Write output to file
*
* @param output_file - name of the output file
* @param output - output data
* @param count - number of element in output
*/
void WriteOutput(const char* output_file, const void* output, const size_t count)
{
FILE* file = fopen(output_file, "wb");
CHECK(file != NULL);
printf("Writing result to file: %s\n", output_file);
size_t count_written = fwrite(output, sizeof(char), count, file);
CHECK(count_written == count);
printf("Output data size: %zu\n", count_written);
fclose(file);
}
int main(int argc, char* argv[])
{
// Create a context
rml_context context = NULL;
RML_CHECK(rmlCreateDefaultContext(NULL, &context));
// Set model parameters
#if defined(_WIN32)
const rml_char* model_path = L"path/model";
#else
const rml_char* model_path = "path/model";
#endif
// Set input file
const char* input_file = "path/input";
// Set output file
const char* output_file = "path/output";
// Load model
rml_graph graph = NULL;
RML_CHECK(rmlLoadGraphFromFile(model_path, &graph));
rml_model model = NULL;
RML_CHECK(rmlCreateModelFromGraph(context, graph, &model));
// Get initial input tensor information
rml_strings input_names;
RML_CHECK(rmlGetGraphInputNames(graph, &input_names));
CHECK(input_names.num_items == MAX_INPUTS);
rml_tensor_info input_info;
RML_CHECK(rmlGetModelInputInfo(model, input_names.items[0], &input_info));
CHECK(input_info.layout == RML_LAYOUT_NHWC || input_info.layout == RML_LAYOUT_NCHW);
// Set unspecified input tensor dimensions if required
if (input_info.layout == RML_LAYOUT_NHWC)
{
input_info.shape[0] = 1;
input_info.shape[1] = 600;
input_info.shape[2] = 800;
}
else if (input_info.layout == RML_LAYOUT_NCHW)
{
input_info.shape[0] = 1;
input_info.shape[2] = 600;
input_info.shape[3] = 800;
}
RML_CHECK(rmlSetModelInputInfo(model, input_names.items[0], &input_info));
// Prepare model for inference
RML_CHECK(rmlPrepareModel(model));
// Create input tensor
rml_tensor input_tensor = NULL;
RML_CHECK(rmlCreateTensor(context, &input_info, RML_ACCESS_MODE_WRITE_ONLY, &input_tensor));
// Map tensor data
size_t data_size = 0;
void* data = NULL;
RML_CHECK(rmlMapTensor(input_tensor, &data, &data_size));
// Copy data
void* file_data = ReadInput(input_file);
memcpy(data, file_data, data_size);
// Unmap tensor data
free(file_data);
RML_CHECK(rmlUnmapTensor(input_tensor, data));
// Set model input
RML_CHECK(rmlSetModelInput(model, input_names.items[0], input_tensor));
// Get output tensor information
rml_tensor_info output_info;
RML_CHECK(rmlGetModelOutputInfo(model, NULL, &output_info));
// Create output tensor
rml_tensor output_tensor = NULL;
RML_CHECK(rmlCreateTensor(context, &output_info, RML_ACCESS_MODE_READ_ONLY, &output_tensor));
// Set model output
RML_CHECK(rmlSetModelOutput(model, NULL, output_tensor));
// Run inference
RML_CHECK(rmlInfer(model));
// Get data from output tensor
size_t output_size;
void* output_data = NULL;
RML_CHECK(rmlMapTensor(output_tensor, &output_data, &output_size));
// Unmap output data
RML_CHECK(rmlUnmapTensor(output_tensor, &output_data));
// Write the output
WriteOutput(output_file, output_data, output_size);
// Release the input and output tensors
rmlReleaseTensor(input_tensor);
rmlReleaseTensor(output_tensor);
// Release the model
rmlReleaseModel(model);
// Release the context
rmlReleaseContext(context);
}