Unverified Commit 31b40352 authored by Chao Liu's avatar Chao Liu Committed by GitHub
Browse files

Merge pull request #16 from ROCmSoftwarePlatform/develop

Merge develop into master
parents 5781adf5 b62bf8c3
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2017 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_HANDLE_HPP_
#define GUARD_OLC_HANDLE_HPP_
#include <kernel.hpp>
#include <stringutils.hpp>
#include <target_properties.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <cstdio>
#include <cstring>
#include <ios>
#include <sstream>
#include <memory>
#include <vector>
#include <unordered_map>
namespace online_compile {
struct HandleImpl;
struct Handle
{
friend struct TargetProperties;
Handle();
Handle(hipStream_t stream);
Handle(Handle&&) noexcept;
~Handle();
hipStream_t GetStream() const;
void SetStream(hipStream_t streamID) const;
KernelInvoke AddKernel(const std::string& algorithm,
const std::string& network_config,
const std::string& program_name,
const std::string& kernel_name,
const std::vector<size_t>& vld,
const std::vector<size_t>& vgd,
const std::string& params,
std::size_t cache_index = 0) const;
bool HasKernel(const std::string& algorithm, const std::string& network_config) const;
void ClearKernels(const std::string& algorithm, const std::string& network_config) const;
auto GetKernels(const std::string& algorithm, const std::string& network_config) const
{
return this->GetKernelsImpl(algorithm, network_config) |
boost::adaptors::transformed([this](Kernel k) { return this->Run(k); });
}
KernelInvoke GetKernel(const std::string& algorithm, const std::string& network_config) const
{
auto ks = this->GetKernelsImpl(algorithm, network_config);
if(ks.empty())
{
throw std::runtime_error("looking for default kernel (does not exist): " + algorithm +
", " + network_config);
}
return this->Run(ks.front());
}
KernelInvoke Run(Kernel k) const;
Program LoadProgram(const std::string& program_name, std::string params) const;
bool HasProgram(const std::string& program_name, const std::string& params) const;
void AddProgram(Program prog, const std::string& program_name, const std::string& params) const;
void Finish() const;
std::size_t GetLocalMemorySize() const;
std::size_t GetGlobalMemorySize() const;
std::size_t GetWavefrontWidth() const;
std::size_t GetMaxComputeUnits() const;
std::size_t GetMaxHardwareComputeUnits() const
{
std::size_t num_cu = this->GetMaxComputeUnits();
std::string name = this->GetDeviceName();
return StartsWith(name, "gfx1") ? num_cu * 2 /* CUs per WGP */ : num_cu;
}
std::string GetDeviceName() const;
const TargetProperties& GetTargetProperties() const;
private:
std::string GetDeviceNameImpl() const;
const std::vector<Kernel>& GetKernelsImpl(const std::string& algorithm,
const std::string& network_config) const;
public:
std::ostream& Print(std::ostream& os) const;
static std::string GetDbBasename(const TargetProperties& target, size_t num_cu)
{
auto ret = target.DbId() + [&]() {
std::ostringstream ss;
if(num_cu <= 64)
ss << '_' << num_cu;
else
ss << std::hex << num_cu;
return std::string(ss.str());
}();
return ret;
}
std::string GetDbBasename() const
{
return GetDbBasename(GetTargetProperties(), GetMaxComputeUnits());
}
std::unique_ptr<HandleImpl> impl;
};
inline std::ostream& operator<<(std::ostream& os, const Handle& handle) { return handle.Print(os); }
} // namespace online_compile
#endif // GUARD_OLC_HANDLE_HPP_
#ifndef _HIP_OLC_CHECK_HPP_
#define _HIP_OLC_CHECK_HPP_
#include <hip/hip_runtime.h>
#include <sstream>
#include <vector>
// Here flag can be a constant, variable or function call
#define MY_HIP_CHECK(flag) \
do \
{ \
hipError_t _tmpVal; \
if((_tmpVal = flag) != hipSuccess) \
{ \
std::ostringstream ostr; \
ostr << "HIP Function Failed (" << __FILE__ << "," << __LINE__ << ") " \
<< hipGetErrorString(_tmpVal); \
throw std::runtime_error(ostr.str()); \
} \
} while(0)
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2019 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef OLC_GUARD_OLC_HIP_BUILD_UTILS_HPP
#define OLC_GUARD_OLC_HIP_BUILD_UTILS_HPP
#include <target_properties.hpp>
#include <kernel.hpp>
#include <boost/optional.hpp>
#include <string>
namespace online_compile {
boost::filesystem::path HipBuild(boost::optional<online_compile::TmpDir>& tmp_dir,
const std::string& filename,
std::string src,
std::string params,
const TargetProperties& target,
bool sources_already_reside_on_filesystem = false);
void bin_file_to_str(const boost::filesystem::path& file, std::string& buf);
struct external_tool_version_t
{
int major = -1;
int minor = -1;
int patch = -1;
friend bool operator>(const external_tool_version_t& lhs, const external_tool_version_t& rhs);
friend bool operator<(const external_tool_version_t& lhs, const external_tool_version_t& rhs);
friend bool operator>=(const external_tool_version_t& lhs, const external_tool_version_t& rhs);
friend bool operator<=(const external_tool_version_t& lhs, const external_tool_version_t& rhs);
};
external_tool_version_t HipCompilerVersion();
bool IsHccCompiler();
bool IsHipClangCompiler();
class LcOptionTargetStrings
{
public:
const std::string& device;
const std::string xnack;
private:
const std::string sramecc;
const std::string sramecc_reported;
public:
const std::string targetId;
LcOptionTargetStrings(const TargetProperties& target)
: device(target.Name()),
xnack([&]() -> std::string {
if(target.Xnack())
return std::string{":xnack"} + (*target.Xnack() ? "+" : "-");
return {};
}()),
sramecc([&]() -> std::string {
if(target.Sramecc())
return std::string{":sramecc"} + (*target.Sramecc() ? "+" : "-");
return {};
}()),
sramecc_reported([&]() -> std::string {
if(target.SrameccReported())
return std::string{":sramecc"} + (*target.SrameccReported() ? "+" : "-");
return {};
}()),
targetId(device + sramecc + xnack)
{
}
};
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2017 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_HIPOC_KERNEL_HPP
#define GUARD_OLC_HIPOC_KERNEL_HPP
#include <array>
#include <cassert>
#include <hipoc_program.hpp>
#include <stringutils.hpp>
#include <manage_ptr.hpp>
#include <op_kernel_args.hpp>
#include <hipCheck.hpp>
#include <vector>
#include <memory>
namespace online_compile {
using HipEventPtr = OLC_MANAGE_PTR(hipEvent_t, hipEventDestroy);
inline HipEventPtr make_hip_event()
{
hipEvent_t result = nullptr;
MY_HIP_CHECK(hipEventCreate(&result));
return HipEventPtr{result};
}
template <class T, class U>
struct KernelArgsPair
{
static const int alignment = sizeof(U);
static const int padding = (alignment - (sizeof(T) % alignment)) % alignment;
static const int second_index = sizeof(T) + padding;
KernelArgsPair(T x, U y)
{
new(buffer) T(x); // NOLINT (clang-analyzer-cplusplus.PlacementNew)
new(buffer + second_index) U(y);
}
char buffer[second_index + sizeof(U)] = {};
};
template <class... Ts>
struct KernelArgsPack;
template <class T, class U, class... Ts>
struct KernelArgsPack<T, U, Ts...>
{
using data_t = KernelArgsPack<KernelArgsPair<T, U>, Ts...>;
KernelArgsPack(T x, U y, Ts... xs) : data(KernelArgsPair<T, U>(x, y), xs...) {}
data_t data;
};
template <class T>
struct KernelArgsPack<T>
{
KernelArgsPack(T x) : head(x) {}
T head;
};
template <class... Ts>
struct KernelArgs
{
KernelArgs(Ts... xs) : pack(xs...) { std::fill(std::begin(hidden), std::end(hidden), 0); }
KernelArgsPack<Ts...> pack;
uint64_t hidden[6] = {};
};
struct HIPOCKernelInvoke
{
hipStream_t stream = nullptr;
hipFunction_t fun = nullptr;
std::array<size_t, 3> ldims = {};
std::array<size_t, 3> gdims = {};
std::string name;
std::function<void(hipEvent_t, hipEvent_t)> callback;
// Workaround for aggregate types in c++11
HIPOCKernelInvoke() {}
HIPOCKernelInvoke(hipStream_t pstream,
hipFunction_t pfun,
std::array<size_t, 3> pldims,
std::array<size_t, 3> pgdims,
std::string pname,
std::function<void(hipEvent_t, hipEvent_t)> pcallback)
: stream(pstream), fun(pfun), ldims(pldims), gdims(pgdims), name(pname), callback(pcallback)
{
}
void operator()(std::vector<OpKernelArg>& any_args) const
{
char hip_args[256] = {0};
auto sz_left = any_args[0].size();
memcpy(hip_args, &(any_args[0].buffer[0]), any_args[0].size());
for(unsigned long idx = 1; idx < any_args.size(); idx++)
{
auto& any_arg = any_args[idx];
unsigned long alignment = any_arg.size();
unsigned long padding = (alignment - (sz_left % alignment)) % alignment;
unsigned long second_index = sz_left + padding;
memcpy(hip_args + second_index, &(any_arg.buffer[0]), any_arg.size());
sz_left = second_index + alignment;
}
run(hip_args, sz_left);
}
template <class... Ts>
void operator()(Ts... xs) const
{
KernelArgs<Ts...> args{xs...};
run(&args, sizeof(args));
}
void run(void* args, std::size_t size) const;
const std::string& GetName() const { return name; }
};
struct HIPOCKernel
{
HIPOCProgram program;
std::string name;
std::array<size_t, 3> ldims = {};
std::array<size_t, 3> gdims = {};
std::string kernel_module;
hipFunction_t fun = nullptr;
HIPOCKernel() {}
HIPOCKernel(HIPOCProgram p,
const std::string kernel_name,
std::vector<size_t> local_dims,
std::vector<size_t> global_dims)
: program(p), name(kernel_name)
{
assert(!local_dims.empty() && local_dims.size() <= 3);
assert(!global_dims.empty() && global_dims.size() <= 3);
ldims.fill(1);
gdims.fill(1);
std::copy(local_dims.begin(), local_dims.end(), ldims.begin());
std::copy(global_dims.begin(), global_dims.end(), gdims.begin());
kernel_module = name;
MY_HIP_CHECK(hipModuleGetFunction(&fun, program.GetModule(), kernel_module.c_str()));
}
HIPOCKernelInvoke Invoke(hipStream_t stream,
std::function<void(hipEvent_t, hipEvent_t)> callback = nullptr) const;
};
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2017 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_HIPOC_PROGRAM_HPP
#define GUARD_OLC_HIPOC_PROGRAM_HPP
#include <target_properties.hpp>
#include <manage_ptr.hpp>
#include <hipoc_program_impl.hpp>
#include <boost/filesystem/path.hpp>
#include <hip/hip_runtime_api.h>
#include <string>
namespace online_compile {
struct HIPOCProgramImpl;
struct HIPOCProgram
{
HIPOCProgram();
/// This ctor builds the program from source, initializes module.
/// Also either CO pathname (typically if offline tools were used)
/// or binary blob (if comgr was used to build the program)
/// is initialized. GetModule(), GetCodeObjectPathname(),
/// GetCodeObjectBlob() return appropriate data after this ctor.
/// Other ctors only guarantee to initialize module.
HIPOCProgram(const std::string& program_name,
std::string params,
const TargetProperties& target);
HIPOCProgram(const std::string& program_name, const boost::filesystem::path& hsaco);
std::shared_ptr<const HIPOCProgramImpl> impl;
hipModule_t GetModule() const;
/// \return Pathname of CO file, if it resides on the filesystem.
boost::filesystem::path GetCodeObjectPathname() const;
/// \return Copy of in-memory CO blob.
std::string GetCodeObjectBlob() const;
/// \return True if CO blob resides in-memory.
/// False if CO resides on filesystem.
bool IsCodeObjectInMemory() const;
};
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2021 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_HIPOC_PROGRAM_IMPL_HPP
#define GUARD_OLC_HIPOC_PROGRAM_IMPL_HPP
#include <target_properties.hpp>
#include <manage_ptr.hpp>
#include <tmp_dir.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/optional.hpp>
#include <hip/hip_runtime_api.h>
namespace online_compile {
using hipModulePtr = OLC_MANAGE_PTR(hipModule_t, hipModuleUnload);
struct HIPOCProgramImpl
{
HIPOCProgramImpl(){};
HIPOCProgramImpl(const std::string& program_name, const boost::filesystem::path& filespec);
HIPOCProgramImpl(const std::string& program_name,
std::string params,
const TargetProperties& target_);
std::string program;
TargetProperties target;
boost::filesystem::path hsaco_file;
hipModulePtr module;
boost::optional<TmpDir> dir;
std::vector<char> binary;
void
BuildCodeObjectInFile(std::string& params, const std::string& src, const std::string& filename);
void BuildCodeObject(std::string params);
};
} // namespace online_compile
#endif // GUARD_OLC_HIPOC_PROGRAM_IMPL_HPP
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2017 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_KERNEL_HPP
#define GUARD_OLC_KERNEL_HPP
#include <string>
#include <vector>
#include <hipoc_kernel.hpp>
namespace online_compile {
std::string GetKernelSrc(std::string name);
std::string GetKernelInc(std::string key);
std::vector<std::string> GetKernelIncList();
std::vector<std::string> GetHipKernelIncList();
using Kernel = HIPOCKernel;
using KernelInvoke = HIPOCKernelInvoke;
using Program = HIPOCProgram;
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2019 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_KERNEL_BUILD_PARAMETERS_HPP_
#define GUARD_OLC_KERNEL_BUILD_PARAMETERS_HPP_
#include <algorithm>
#include <cassert>
#include <initializer_list>
#include <string>
#include <vector>
namespace online_compile {
namespace kbp {
struct Option
{
};
} // namespace kbp
enum class ParameterTypes
{
Define,
Option,
};
struct KernelBuildParameter
{
ParameterTypes type;
std::string name;
std::string value;
};
class KernelBuildParameters
{
public:
struct KBPInit
{
friend class KernelBuildParameters;
KBPInit(const std::string& name, const std::string& value = "")
: data{ParameterTypes::Define, name, value}
{
}
template <class TValue, class = decltype(std::to_string(std::declval<TValue>()))>
KBPInit(const std::string& name, const TValue& value) : KBPInit(name, std::to_string(value))
{
}
KBPInit(kbp::Option, const std::string& name, const std::string& value = "")
: data{ParameterTypes::Option, name, value}
{
}
template <class TValue, class = decltype(std::to_string(std::declval<TValue>()))>
KBPInit(kbp::Option, const std::string& name, const TValue& value)
: KBPInit(kbp::Option{}, name, std::to_string(value))
{
}
private:
KernelBuildParameter data{};
};
KernelBuildParameters() = default;
KernelBuildParameters(const std::initializer_list<KBPInit>& defines_)
{
options.reserve(defines_.size());
for(const auto& define : defines_)
{
assert(ValidateUniqueness(define.data.name));
options.push_back(define.data);
}
}
bool Empty() const { return options.empty(); }
void Define(const std::string& name, const std::string& value = "")
{
assert(ValidateUniqueness(name));
options.push_back({ParameterTypes::Define, name, value});
}
template <class TValue, class = decltype(std::to_string(std::declval<TValue>()))>
void Define(const std::string& name, const TValue& value)
{
Define(name, std::to_string(value));
}
KernelBuildParameters& operator<<(const KernelBuildParameters& other)
{
std::copy(other.options.begin(), other.options.end(), std::back_inserter(options));
return *this;
}
template <class TFor>
std::string GenerateFor(TFor&&) const
{
return TFor::Generate(options);
}
private:
std::vector<KernelBuildParameter> options = {};
bool ValidateUniqueness(const std::string& name) const
{
const auto eq = [=](const auto& item) { return item.name == name; };
return std::find_if(options.begin(), options.end(), eq) == options.end();
}
};
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2017 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
/* ************************************************************************
* Copyright 2015 Vratis, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ************************************************************************ */
#ifndef GUARD_OLC_KERNEL_CACHE_HPP_
#define GUARD_OLC_KERNEL_CACHE_HPP_
#include <handle.hpp>
#include <kernel.hpp>
#include <simple_hash.hpp>
#include <string>
#include <unordered_map>
#include <vector>
namespace online_compile {
/**
* @brief The KernelCache class Build and cache kernels
*
*/
class KernelCache
{
public:
using Key = std::pair<std::string, std::string>;
using KernelMap = std::unordered_map<Key, std::vector<Kernel>, SimpleHash>;
using ProgramMap = std::unordered_map<Key, Program, SimpleHash>;
Kernel AddKernel(const Handle& h,
const std::string& algorithm,
const std::string& network_config,
const std::string& program_name,
const std::string& kernel_name,
const std::vector<size_t>& vld,
const std::vector<size_t>& vgd,
std::string params = "",
std::size_t cache_index = 0);
void AddKernel(Key key, Kernel k, std::size_t cache_index);
void ClearKernels(const std::string& algorithm, const std::string& network_config);
const std::vector<Kernel>& GetKernels(const std::string& algorithm,
const std::string& network_config);
bool HasKernels(const std::string& algorithm, const std::string& network_config) const;
bool HasProgram(const std::string& name, const std::string& params) const;
void AddProgram(Program prog, const std::string& program_name, std::string params);
KernelCache();
private:
KernelMap kernel_map;
ProgramMap program_map;
};
} // namespace online_compile
#endif // GUARD_OLC_KERNEL_CACHE_HPP_
#ifndef _OLC_LOGGER_HPP_
#define _OLC_LOGGER_HPP_
#include <fstream>
namespace online_compile {
enum class LogLevel
{
Quiet = 1,
Error = 2,
Warning = 3,
Info = 4,
Info2 = 5
};
std::ostream& fdt_log(LogLevel level, const char* header, const char* content);
std::ostream& fdt_log();
void fdt_log_flush();
}; // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2017 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_MANAGE_PTR_HPP
#define GUARD_OLC_MANAGE_PTR_HPP
#include <memory>
#include <type_traits>
namespace online_compile {
template <class F, F f>
struct manage_deleter
{
template <class T>
void operator()(T* x) const
{
if(x != nullptr)
{
(void)f(x); // NOLINT (cppcoreguidelines-owning-memory)
}
}
};
struct null_deleter
{
template <class T>
void operator()(T* /*x*/) const
{
}
};
template <class T, class F, F f>
using manage_ptr = std::unique_ptr<T, manage_deleter<F, f>>;
template <class T>
struct element_type
{
using type = typename T::element_type;
};
template <class T>
using remove_ptr = typename std::
conditional<std::is_pointer<T>::value, std::remove_pointer<T>, element_type<T>>::type::type;
template <class T>
using shared = std::shared_ptr<remove_ptr<T>>;
} // namespace online_compile
#define OLC_MANAGE_PTR(T, F) \
online_compile::manage_ptr<typename std::remove_pointer<T>::type, decltype(&F), &F> // NOLINT
#endif
#ifndef GUARD_OLC_MD5_HPP
#define GUARD_OLC_MD5_HPP
#include <string>
namespace online_compile {
std::string md5(std::string s);
} // namespace online_compile
#endif
#ifndef OLC_GUARD_MLOPEN_OP_KERNEL_ARGS_HPP
#define OLC_GUARD_MLOPEN_OP_KERNEL_ARGS_HPP
#include <type_traits>
#include <cstdint>
#include <half.hpp>
#include <boost/container/small_vector.hpp>
namespace online_compile {
struct OpKernelArg
{
OpKernelArg(char val, size_t sz) : buffer(sz) { std::fill(buffer.begin(), buffer.end(), val); }
template <typename T>
OpKernelArg(T arg) : buffer(sizeof(T))
{
static_assert(std::is_trivial<T>{} || std::is_same<T, half_float::half>{},
"Only for trivial types");
*(reinterpret_cast<T*>(buffer.data())) = arg;
}
template <typename T>
OpKernelArg(T* arg) // NOLINT
: buffer(sizeof(T*))
{
*(reinterpret_cast<T**>(buffer.data())) = arg;
is_ptr = true;
}
std::size_t size() const { return buffer.size(); };
boost::container::small_vector<char, 8> buffer;
bool is_ptr = false;
};
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2018 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_SIMPLE_HASH_HPP
#define GUARD_OLC_SIMPLE_HASH_HPP
#include <string>
namespace online_compile {
struct SimpleHash
{
size_t operator()(const std::pair<std::string, std::string>& p) const
{
using std::hash;
return (hash<std::string>()(p.first) ^ hash<std::string>()(p.second));
}
};
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2017 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_STRINGUTILS_HPP
#define GUARD_OLC_STRINGUTILS_HPP
#include <algorithm>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>
#include <sstream>
#define OLC_STRINGIZE_1(...) #__VA_ARGS__
#define OLC_STRINGIZE(...) OLC_STRINGIZE_1(__VA_ARGS__)
namespace online_compile {
inline std::string
ReplaceString(std::string subject, const std::string& search, const std::string& replace)
{
size_t pos = 0;
while((pos = subject.find(search, pos)) != std::string::npos)
{
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
inline bool EndsWith(const std::string& value, const std::string& suffix)
{
if(suffix.size() > value.size())
return false;
else
return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin());
}
template <class Strings>
inline std::string JoinStrings(Strings strings, std::string delim)
{
auto it = strings.begin();
if(it == strings.end())
return "";
auto nit = std::next(it);
return std::accumulate(
nit, strings.end(), *it, [&](std::string x, std::string y) { return x + delim + y; });
}
template <class F>
static inline std::string TransformString(std::string s, F f)
{
std::transform(s.begin(), s.end(), s.begin(), f);
return s;
}
inline std::string ToUpper(std::string s) { return TransformString(std::move(s), ::toupper); }
inline bool StartsWith(const std::string& value, const std::string& prefix)
{
if(prefix.size() > value.size())
return false;
else
return std::equal(prefix.begin(), prefix.end(), value.begin());
}
inline std::string RemovePrefix(std::string s, std::string prefix)
{
if(StartsWith(s, prefix))
return s.substr(prefix.length());
else
return s;
}
inline std::vector<std::string> SplitSpaceSeparated(const std::string& in)
{
std::istringstream ss(in);
std::istream_iterator<std::string> begin(ss), end;
return {begin, end};
}
inline std::vector<std::string> SplitSpaceSeparated(const std::string& in,
const std::vector<std::string>& dontSplitAfter)
{
std::vector<std::string> rv;
std::istringstream ss(in);
std::string s;
while(ss >> s)
{
if(std::any_of(dontSplitAfter.begin(), dontSplitAfter.end(), [&](const auto& dont) {
return dont == s;
}))
{
std::string s2;
if(ss >> s2)
{
s += std::string(" ").append(s2); // Exactly one space is important.
rv.push_back(s);
continue;
}
throw std::runtime_error("Error parsing string: '" + in + '\'');
}
rv.push_back(s);
}
return rv;
}
} // namespace online_compile
#endif // GUARD_OLC_STRINGUTILS_HPP
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2020 Advanced Micro Devices, Inc.
*
* 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.
*
*******************************************************************************/
#ifndef GUARD_OLC_TARGET_PROPERTIES_HPP
#define GUARD_OLC_TARGET_PROPERTIES_HPP
#include <boost/optional.hpp>
#include <string>
namespace online_compile {
struct Handle;
struct TargetProperties
{
const std::string& Name() const { return name; }
const std::string& DbId() const { return dbId; }
boost::optional<bool> Xnack() const { return xnack; }
boost::optional<bool> Sramecc() const { return sramecc; }
boost::optional<bool> SrameccReported() const { return sramecc_reported; }
void Init(const Handle*);
private:
void InitDbId();
std::string name;
std::string dbId;
boost::optional<bool> xnack = boost::none;
boost::optional<bool> sramecc = boost::none;
boost::optional<bool> sramecc_reported = boost::none;
};
} // namespace online_compile
#endif // GUARD_OLC_TARGET_PROPERTIES_HPP
#ifndef GUARD_OLC_TMP_DIR_HPP
#define GUARD_OLC_TMP_DIR_HPP
#include <string>
#include <boost/filesystem/path.hpp>
namespace online_compile {
void SystemCmd(std::string cmd);
struct TmpDir
{
boost::filesystem::path path;
TmpDir(std::string prefix);
TmpDir(TmpDir const&) = delete;
TmpDir& operator=(TmpDir const&) = delete;
void Execute(std::string exe, std::string args) const;
~TmpDir();
};
} // namespace online_compile
#endif
#ifndef GUARD_OLC_WRITE_FILE_HPP
#define GUARD_OLC_WRITE_FILE_HPP
#include <boost/filesystem.hpp>
#include <manage_ptr.hpp>
#include <fstream>
namespace online_compile {
using FilePtr = OLC_MANAGE_PTR(FILE*, std::fclose);
inline void WriteFile(const std::string& content, const boost::filesystem::path& name)
{
// std::cerr << "Write file: " << name << std::endl;
FilePtr f{std::fopen(name.string().c_str(), "w")};
if(std::fwrite(content.c_str(), 1, content.size(), f.get()) != content.size())
throw std::runtime_error("Failed to write to file");
}
inline void WriteFile(const std::vector<char>& content, const boost::filesystem::path& name)
{
// std::cerr << "Write file: " << name << std::endl;
FilePtr f{std::fopen(name.string().c_str(), "w")};
if(std::fwrite(&content[0], 1, content.size(), f.get()) != content.size())
throw std::runtime_error("Failed to write to file");
}
} // namespace online_compile
#endif
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2021 Advanced Micro Devices, Inc.
*
* 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 <algorithm>
#include <map>
#include <stdexcept>
// clang-format off
${KERNELS_DECLS}
// clang-format on
namespace online_compile {
const std::map<std::string, std::string>& kernels()
{
static const std::map<std::string, std::string> data{${INIT_KERNELS}};
return data;
}
std::string GetKernelSrc(std::string name)
{
// Use the base name of the string
int start = 0;
auto slash = static_cast<int>(name.find_last_of("/\\"));
if(slash != std::string::npos)
{
start = slash + 1;
}
int len = name.size();
auto ex = static_cast<int>(name.rfind('.'));
if(ex != std::string::npos)
{
len = ex - start;
}
auto key = name.substr(start, len);
// Convert to uppercase
std::transform(key.begin(), key.end(), key.begin(), ::toupper);
auto it = kernels().find(key);
if(it == kernels().end())
throw std::runtime_error("Failed to load kernel source: " + key);
return it->second;
}
} // namespace online_compile
/*******************************************************************************
*
* MIT License
*
* Copyright (c) 2019 Advanced Micro Devices, Inc.
*
* 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 "olc_kernel_includes.h"
#include <algorithm>
#include <map>
#include <stdexcept>
#include <vector>
namespace online_compile {
static inline bool EndsWith(const std::string& value, const std::string& suffix)
{
if(suffix.size() > value.size())
return false;
else
return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin());
}
const std::map<std::string, std::string>& kernel_includes()
{
static const std::map<std::string, std::string> data{${INIT_KERNELS}};
return data;
}
std::string GetKernelInc(std::string key)
{
auto it = kernel_includes().find(key);
if(it == kernel_includes().end())
throw std::runtime_error("Failed to load kernel source: " + key);
return it->second;
}
std::vector<std::string> GetKernelIncList()
{
std::vector<std::string> keys;
auto m = kernel_includes();
std::transform(m.begin(),
m.end(),
std::back_inserter(keys),
[](decltype(m)::value_type const& pair) { return pair.first; });
return keys;
}
std::vector<std::string> GetHipKernelIncList()
{
auto keys = GetKernelIncList();
keys.erase(std::remove_if(keys.begin(),
keys.end(),
[&](const auto& key) {
return !(EndsWith(key, ".hpp") || EndsWith(key, ".h"));
}),
keys.end());
return keys;
}
} // namespace online_compile
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment