mnist.cpp 4.55 KB
Newer Older
Scott Thornton's avatar
Scott Thornton committed
1
2
3
#include <cstdio>
#include <string>
#include <fstream>
Scott Thornton's avatar
Scott Thornton committed
4
#include <numeric>
Scott Thornton's avatar
Scott Thornton committed
5
6
#include <stdexcept>

Paul's avatar
Paul committed
7
#include <migraphx/onnx.hpp>
Scott Thornton's avatar
Scott Thornton committed
8

Paul's avatar
Paul committed
9
10
11
#include <migraphx/gpu/target.hpp>
#include <migraphx/gpu/hip.hpp>
#include <migraphx/generate.hpp>
Scott Thornton's avatar
Scott Thornton committed
12

wsttiger's avatar
wsttiger committed
13
#include "softmax.hpp"
14

15
auto reverse_int(unsigned int i)
Scott Thornton's avatar
Scott Thornton committed
16
{
Paul's avatar
Paul committed
17
18
19
20
    unsigned char c1;
    unsigned char c2;
    unsigned char c3;
    unsigned char c4;
21
22
23
24
25
26
27
    c1 = i & 255u;
    c2 = (i >> 8u) & 255u;
    c3 = (i >> 16u) & 255u;
    c4 = (i >> 24u) & 255u;
    return (static_cast<unsigned int>(c1) << 24u) + (static_cast<unsigned int>(c2) << 16u) +
           (static_cast<unsigned int>(c3) << 8u) + c4;
};
Scott Thornton's avatar
Scott Thornton committed
28

Paul's avatar
Paul committed
29
30
std::vector<float>
read_mnist_images(const std::string& full_path, int& number_of_images, int& image_size)
31
{
32
    using uchar = unsigned char;
Scott Thornton's avatar
Scott Thornton committed
33
34
35
36
37

    std::ifstream file(full_path, std::ios::binary);

    if(file.is_open())
    {
Paul's avatar
Paul committed
38
        int magic_number = 0;
Paul's avatar
Paul committed
39
40
        int n_rows       = 0;
        int n_cols       = 0;
Scott Thornton's avatar
Scott Thornton committed
41

42
43
        file.read(reinterpret_cast<char*>(&magic_number), sizeof(magic_number));
        magic_number = reverse_int(magic_number);
Scott Thornton's avatar
Scott Thornton committed
44
45
46
47

        if(magic_number != 2051)
            throw std::runtime_error("Invalid MNIST image file!");

48
49
        file.read(reinterpret_cast<char*>(&number_of_images), sizeof(number_of_images));
        number_of_images = reverse_int(number_of_images);
Scott Thornton's avatar
Scott Thornton committed
50
        file.read(reinterpret_cast<char*>(&n_rows), sizeof(n_rows));
51
52
53
        n_rows = reverse_int(n_rows);
        file.read(reinterpret_cast<char*>(&n_cols), sizeof(n_cols));
        n_cols = reverse_int(n_cols);
Scott Thornton's avatar
Scott Thornton committed
54
55
56
57
58
59
60
61
62

        image_size = n_rows * n_cols;

        std::vector<float> result(number_of_images * image_size);
        for(int i = 0; i < number_of_images; i++)
        {
            for(int j = 0; j < image_size; j++)
            {
                uchar tmp;
63
                file.read(reinterpret_cast<char*>(&tmp), 1);
Scott Thornton's avatar
Scott Thornton committed
64
65
66
67
68
69
70
71
72
73
74
                result[i * image_size + j] = tmp / 255.0;
            }
        }
        return result;
    }
    else
    {
        throw std::runtime_error("Cannot open file `" + full_path + "`!");
    }
}

Paul's avatar
Paul committed
75
std::vector<int32_t> read_mnist_labels(const std::string& full_path, int& number_of_labels)
Scott Thornton's avatar
Scott Thornton committed
76
{
77
    using uchar = unsigned char;
Scott Thornton's avatar
Scott Thornton committed
78
79
80
81
82
83

    std::ifstream file(full_path, std::ios::binary);

    if(file.is_open())
    {
        int magic_number = 0;
84
85
        file.read(reinterpret_cast<char*>(&magic_number), sizeof(magic_number));
        magic_number = reverse_int(magic_number);
Scott Thornton's avatar
Scott Thornton committed
86
87
88
89

        if(magic_number != 2049)
            throw std::runtime_error("Invalid MNIST label file!");

90
91
        file.read(reinterpret_cast<char*>(&number_of_labels), sizeof(number_of_labels));
        number_of_labels = reverse_int(number_of_labels);
Scott Thornton's avatar
Scott Thornton committed
92
93
94
95
96

        std::vector<int32_t> result(number_of_labels);
        for(int i = 0; i < number_of_labels; i++)
        {
            uchar tmp;
97
            file.read(reinterpret_cast<char*>(&tmp), 1);
Scott Thornton's avatar
Scott Thornton committed
98
99
100
101
102
103
104
105
106
107
108
109
            result[i] = tmp;
        }
        return result;
    }
    else
    {
        throw std::runtime_error("Unable to open file `" + full_path + "`!");
    }
}

int main(int argc, char const* argv[])
{
110
    if(argc > 3)
Scott Thornton's avatar
Scott Thornton committed
111
112
113
114
115
116
117
118
119
120
    {
        std::string datafile        = argv[2];
        std::string labelfile       = argv[3];
        int nimages                 = -1;
        int image_size              = -1;
        int nlabels                 = -1;
        std::vector<float> input    = read_mnist_images(datafile, nimages, image_size);
        std::vector<int32_t> labels = read_mnist_labels(labelfile, nlabels);

        std::string file = argv[1];
Paul's avatar
Paul committed
121
        auto prog        = migraphx::parse_onnx(file);
122
        std::cout << prog << std::endl << std::endl;
Paul's avatar
Paul committed
123
124
        prog.compile(migraphx::gpu::target{});
        auto s = migraphx::shape{migraphx::shape::float_type, {1, 1, 28, 28}};
Scott Thornton's avatar
Scott Thornton committed
125
        std::cout << s << std::endl;
Scott Thornton's avatar
Scott Thornton committed
126
        auto ptr = input.data();
Paul's avatar
Paul committed
127
        migraphx::program::parameter_map m;
128
        m["output"] =
Paul's avatar
Paul committed
129
            migraphx::gpu::to_gpu(migraphx::generate_argument(prog.get_parameter_shape("output")));
Scott Thornton's avatar
Scott Thornton committed
130
        for(int i = 0; i < 20; i++)
Scott Thornton's avatar
Scott Thornton committed
131
        {
132
            std::cout << "label: " << labels[i] << "  ---->  ";
133
134
135
            m["0"]       = migraphx::gpu::to_gpu(migraphx::argument{s, &ptr[784 * i]});
            auto results = prog.eval(m).back();
            auto result  = migraphx::gpu::from_gpu(results);
Scott Thornton's avatar
Scott Thornton committed
136
137
138
            std::vector<float> logits;
            result.visit([&](auto output) { logits.assign(output.begin(), output.end()); });
            std::vector<float> probs = softmax(logits);
Scott Thornton's avatar
Scott Thornton committed
139
140
            for(auto x : probs)
                std::cout << x << "  ";
141
            std::cout << std::endl;
Scott Thornton's avatar
Scott Thornton committed
142
        }
143
        std::cout << std::endl;
Scott Thornton's avatar
Scott Thornton committed
144
145
    }
}