1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #include "ClContextDeserializer.hpp"
7*89c4ff92SAndroid Build Coastguard Worker #include "ClContextSchema_generated.h"
8*89c4ff92SAndroid Build Coastguard Worker
9*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Exceptions.hpp>
10*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/NumericCast.hpp>
11*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Logging.hpp>
12*89c4ff92SAndroid Build Coastguard Worker
13*89c4ff92SAndroid Build Coastguard Worker #include <flatbuffers/flexbuffers.h>
14*89c4ff92SAndroid Build Coastguard Worker
15*89c4ff92SAndroid Build Coastguard Worker #include <fmt/format.h>
16*89c4ff92SAndroid Build Coastguard Worker
17*89c4ff92SAndroid Build Coastguard Worker #include <cstdlib>
18*89c4ff92SAndroid Build Coastguard Worker #include <fstream>
19*89c4ff92SAndroid Build Coastguard Worker #include <iostream>
20*89c4ff92SAndroid Build Coastguard Worker #include <vector>
21*89c4ff92SAndroid Build Coastguard Worker
22*89c4ff92SAndroid Build Coastguard Worker
23*89c4ff92SAndroid Build Coastguard Worker #if defined(__linux__)
24*89c4ff92SAndroid Build Coastguard Worker #define SERIALIZER_USE_MMAP 1
25*89c4ff92SAndroid Build Coastguard Worker #if SERIALIZER_USE_MMAP
26*89c4ff92SAndroid Build Coastguard Worker #include <sys/stat.h>
27*89c4ff92SAndroid Build Coastguard Worker #include <sys/mman.h>
28*89c4ff92SAndroid Build Coastguard Worker #include <fcntl.h>
29*89c4ff92SAndroid Build Coastguard Worker #include <unistd.h>
30*89c4ff92SAndroid Build Coastguard Worker #endif
31*89c4ff92SAndroid Build Coastguard Worker #endif
32*89c4ff92SAndroid Build Coastguard Worker
33*89c4ff92SAndroid Build Coastguard Worker namespace armnn
34*89c4ff92SAndroid Build Coastguard Worker {
35*89c4ff92SAndroid Build Coastguard Worker
Deserialize(arm_compute::CLCompileContext & clCompileContext,cl::Context & context,cl::Device & device,const std::string & filePath)36*89c4ff92SAndroid Build Coastguard Worker void ClContextDeserializer::Deserialize(arm_compute::CLCompileContext& clCompileContext,
37*89c4ff92SAndroid Build Coastguard Worker cl::Context& context,
38*89c4ff92SAndroid Build Coastguard Worker cl::Device& device,
39*89c4ff92SAndroid Build Coastguard Worker const std::string& filePath)
40*89c4ff92SAndroid Build Coastguard Worker {
41*89c4ff92SAndroid Build Coastguard Worker std::vector<std::uint8_t> binaryContent;
42*89c4ff92SAndroid Build Coastguard Worker #if !SERIALIZER_USE_MMAP
43*89c4ff92SAndroid Build Coastguard Worker std::ifstream inputFileStream(filePath, std::ios::binary);
44*89c4ff92SAndroid Build Coastguard Worker while (inputFileStream)
45*89c4ff92SAndroid Build Coastguard Worker {
46*89c4ff92SAndroid Build Coastguard Worker char input;
47*89c4ff92SAndroid Build Coastguard Worker inputFileStream.get(input);
48*89c4ff92SAndroid Build Coastguard Worker if (inputFileStream)
49*89c4ff92SAndroid Build Coastguard Worker {
50*89c4ff92SAndroid Build Coastguard Worker binaryContent.push_back(static_cast<std::uint8_t>(input));
51*89c4ff92SAndroid Build Coastguard Worker }
52*89c4ff92SAndroid Build Coastguard Worker }
53*89c4ff92SAndroid Build Coastguard Worker inputFileStream.close();
54*89c4ff92SAndroid Build Coastguard Worker #else
55*89c4ff92SAndroid Build Coastguard Worker struct stat statbuf;
56*89c4ff92SAndroid Build Coastguard Worker int fp = open(filePath.c_str(),O_RDONLY);
57*89c4ff92SAndroid Build Coastguard Worker if (!fp)
58*89c4ff92SAndroid Build Coastguard Worker {
59*89c4ff92SAndroid Build Coastguard Worker ARMNN_LOG(error) << (std::string("Cannot open file ") + filePath);
60*89c4ff92SAndroid Build Coastguard Worker return;
61*89c4ff92SAndroid Build Coastguard Worker }
62*89c4ff92SAndroid Build Coastguard Worker fstat(fp,&statbuf);
63*89c4ff92SAndroid Build Coastguard Worker const unsigned long dataSize = static_cast<unsigned long>(statbuf.st_size);
64*89c4ff92SAndroid Build Coastguard Worker binaryContent.resize(static_cast<long unsigned int>(dataSize));
65*89c4ff92SAndroid Build Coastguard Worker void* ptrmem = mmap(NULL, dataSize,PROT_READ,MAP_PRIVATE,fp,0);
66*89c4ff92SAndroid Build Coastguard Worker if(ptrmem!=MAP_FAILED)
67*89c4ff92SAndroid Build Coastguard Worker {
68*89c4ff92SAndroid Build Coastguard Worker memcpy (binaryContent.data(), ptrmem, dataSize);
69*89c4ff92SAndroid Build Coastguard Worker }
70*89c4ff92SAndroid Build Coastguard Worker close(fp);
71*89c4ff92SAndroid Build Coastguard Worker if(ptrmem == MAP_FAILED)
72*89c4ff92SAndroid Build Coastguard Worker {
73*89c4ff92SAndroid Build Coastguard Worker ARMNN_LOG(error) << (std::string("Cannot map file ") + filePath);
74*89c4ff92SAndroid Build Coastguard Worker return;
75*89c4ff92SAndroid Build Coastguard Worker }
76*89c4ff92SAndroid Build Coastguard Worker #endif
77*89c4ff92SAndroid Build Coastguard Worker
78*89c4ff92SAndroid Build Coastguard Worker DeserializeFromBinary(clCompileContext, context, device, binaryContent);
79*89c4ff92SAndroid Build Coastguard Worker }
80*89c4ff92SAndroid Build Coastguard Worker
DeserializeFromBinary(arm_compute::CLCompileContext & clCompileContext,cl::Context & context,cl::Device & device,const std::vector<uint8_t> & binaryContent)81*89c4ff92SAndroid Build Coastguard Worker void ClContextDeserializer::DeserializeFromBinary(arm_compute::CLCompileContext& clCompileContext,
82*89c4ff92SAndroid Build Coastguard Worker cl::Context& context,
83*89c4ff92SAndroid Build Coastguard Worker cl::Device& device,
84*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t>& binaryContent)
85*89c4ff92SAndroid Build Coastguard Worker {
86*89c4ff92SAndroid Build Coastguard Worker if (binaryContent.data() == nullptr)
87*89c4ff92SAndroid Build Coastguard Worker {
88*89c4ff92SAndroid Build Coastguard Worker throw InvalidArgumentException(fmt::format("Invalid (null) binary content {}",
89*89c4ff92SAndroid Build Coastguard Worker CHECK_LOCATION().AsString()));
90*89c4ff92SAndroid Build Coastguard Worker }
91*89c4ff92SAndroid Build Coastguard Worker
92*89c4ff92SAndroid Build Coastguard Worker size_t binaryContentSize = binaryContent.size();
93*89c4ff92SAndroid Build Coastguard Worker flatbuffers::Verifier verifier(binaryContent.data(), binaryContentSize);
94*89c4ff92SAndroid Build Coastguard Worker if (verifier.VerifyBuffer<ClContext>() == false)
95*89c4ff92SAndroid Build Coastguard Worker {
96*89c4ff92SAndroid Build Coastguard Worker throw ParseException(fmt::format("Buffer doesn't conform to the expected Armnn "
97*89c4ff92SAndroid Build Coastguard Worker "flatbuffers format. size:{0} {1}",
98*89c4ff92SAndroid Build Coastguard Worker binaryContentSize,
99*89c4ff92SAndroid Build Coastguard Worker CHECK_LOCATION().AsString()));
100*89c4ff92SAndroid Build Coastguard Worker }
101*89c4ff92SAndroid Build Coastguard Worker auto clContext = GetClContext(binaryContent.data());
102*89c4ff92SAndroid Build Coastguard Worker
103*89c4ff92SAndroid Build Coastguard Worker for (Program const* program : *clContext->programs())
104*89c4ff92SAndroid Build Coastguard Worker {
105*89c4ff92SAndroid Build Coastguard Worker const char* volatile programName = program->name()->c_str();
106*89c4ff92SAndroid Build Coastguard Worker auto programBinary = program->binary();
107*89c4ff92SAndroid Build Coastguard Worker std::vector<uint8_t> binary(programBinary->begin(), programBinary->begin() + programBinary->size());
108*89c4ff92SAndroid Build Coastguard Worker
109*89c4ff92SAndroid Build Coastguard Worker cl::Program::Binaries binaries{ binary };
110*89c4ff92SAndroid Build Coastguard Worker std::vector<cl::Device> devices {device};
111*89c4ff92SAndroid Build Coastguard Worker cl::Program theProgram(context, devices, binaries);
112*89c4ff92SAndroid Build Coastguard Worker theProgram.build();
113*89c4ff92SAndroid Build Coastguard Worker clCompileContext.add_built_program(programName, theProgram);
114*89c4ff92SAndroid Build Coastguard Worker }
115*89c4ff92SAndroid Build Coastguard Worker }
116*89c4ff92SAndroid Build Coastguard Worker
117*89c4ff92SAndroid Build Coastguard Worker } // namespace armnn
118