blob: 294396c28a0ed75c568309fd884448ce09d2951a [file] [log] [blame]
/*
* Copyright (c) 2020-2021 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "arm_compute/runtime/CL/Utils.h"
#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
#include <fstream>
#include <map>
#include <string>
namespace arm_compute
{
void restore_program_cache_from_file(const std::string &filename)
{
std::ifstream cache_file(filename, std::ios::binary);
if (cache_file.is_open())
{
if (!CLScheduler::get().is_initialised())
{
arm_compute::CLScheduler::get().default_init();
}
while (!cache_file.eof())
{
size_t name_len = 0;
size_t binary_len = 0;
cache_file.read(reinterpret_cast<char *>(&name_len), sizeof(size_t));
cache_file.read(reinterpret_cast<char *>(&binary_len), sizeof(size_t));
if (name_len == 0 || binary_len == 0)
{
break;
}
std::vector<char> tmp(name_len);
std::vector<unsigned char> binary(binary_len);
std::string name;
cache_file.read(tmp.data(), name_len);
name.assign(tmp.data(), name_len);
tmp.resize(binary_len);
cache_file.read(reinterpret_cast<char *>(binary.data()), binary_len);
cl::Context context = arm_compute::CLScheduler::get().context();
cl::Program::Binaries binaries{binary};
std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
cl::Program program(context, devices, binaries);
program.build();
CLKernelLibrary::get().add_built_program(name, program);
}
cache_file.close();
}
}
void save_program_cache_to_file(const std::string &filename)
{
if (CLScheduler::get().is_initialised())
{
std::ofstream cache_file(filename, std::ios::binary);
if (cache_file.is_open())
{
for (const auto &it : CLKernelLibrary::get().get_built_programs())
{
std::vector<std::vector<unsigned char>> binaries = it.second.getInfo<CL_PROGRAM_BINARIES>();
ARM_COMPUTE_ERROR_ON(binaries.size() != 1);
const std::string kernel_name = it.first;
size_t kernel_name_size = kernel_name.length();
size_t binary_size = binaries[0].size();
cache_file.write(reinterpret_cast<char *>(&kernel_name_size), sizeof(size_t));
cache_file.write(reinterpret_cast<char *>(&binary_size), sizeof(size_t));
cache_file.write(kernel_name.c_str(), kernel_name_size);
cache_file.write(reinterpret_cast<const char *>(binaries[0].data()), binaries[0].size());
}
cache_file.close();
}
else
{
ARM_COMPUTE_ERROR("Cannot open cache file");
}
}
}
} // namespace arm_compute