Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Add StreamExecutor kernel types. Reviewers: jlebar, tra Subscribers: parallel_libs-commits Differential Revision: https://reviews.llvm.org/D23138 llvm-svn: 277827
- Loading branch information
Showing
9 changed files
with
383 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
parallel-libs/streamexecutor/include/streamexecutor/Interfaces.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//===-- Interfaces.h - Interfaces to platform-specific impls ----*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// Interfaces to platform-specific StreamExecutor type implementations. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef STREAMEXECUTOR_INTERFACES_H | ||
#define STREAMEXECUTOR_INTERFACES_H | ||
|
||
namespace streamexecutor { | ||
|
||
/// Methods supported by device kernel function objects on all platforms. | ||
class KernelInterface { | ||
// TODO(jhen): Add methods. | ||
}; | ||
|
||
// TODO(jhen): Add other interfaces such as Stream. | ||
|
||
} // namespace streamexecutor | ||
|
||
#endif // STREAMEXECUTOR_INTERFACES_H |
158 changes: 158 additions & 0 deletions
158
parallel-libs/streamexecutor/include/streamexecutor/Kernel.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
//===-- Kernel.h - StreamExecutor kernel types ------------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// Types to represent device kernels (code compiled to run on GPU or other | ||
/// accelerator). | ||
/// | ||
/// The TypedKernel class is used to provide type safety to the user API's | ||
/// launch functions, and the KernelBase class is used like a void* function | ||
/// pointer to perform type-unsafe operations inside StreamExecutor. | ||
/// | ||
/// With the kernel parameter types recorded in the TypedKernel template | ||
/// parameters, type-safe kernel launch functions can be written with signatures | ||
/// like the following: | ||
/// \code | ||
/// template <typename... ParameterTs> | ||
/// void Launch( | ||
/// const TypedKernel<ParameterTs...> &Kernel, ParamterTs... Arguments); | ||
/// \endcode | ||
/// and the compiler will check that the user passes in arguments with types | ||
/// matching the corresponding kernel parameters. | ||
/// | ||
/// A problem is that a TypedKernel template specialization with the right | ||
/// parameter types must be passed as the first argument to the Launch function, | ||
/// and it's just as hard to get the types right in that template specialization | ||
/// as it is to get them right for the kernel arguments. | ||
/// | ||
/// With this problem in mind, it is not recommended for users to specialize the | ||
/// TypedKernel template class themselves, but instead to let the compiler do it | ||
/// for them. When the compiler encounters a device kernel function, it can | ||
/// create a TypedKernel template specialization in the host code that has the | ||
/// right parameter types for that kernel and which has a type name based on the | ||
/// name of the kernel function. | ||
/// | ||
/// For example, if a CUDA device kernel function with the following signature | ||
/// has been defined: | ||
/// \code | ||
/// void Saxpy(float *A, float *X, float *Y); | ||
/// \endcode | ||
/// the compiler can insert the following declaration in the host code: | ||
/// \code | ||
/// namespace compiler_cuda_namespace { | ||
/// using SaxpyKernel = | ||
/// streamexecutor::TypedKernel<float *, float *, float *>; | ||
/// } // namespace compiler_cuda_namespace | ||
/// \endcode | ||
/// and then the user can launch the kernel by calling the StreamExecutor launch | ||
/// function as follows: | ||
/// \code | ||
/// namespace ccn = compiler_cuda_namespace; | ||
/// // Assumes Executor is a pointer to the StreamExecutor on which to | ||
/// // launch the kernel. | ||
/// // | ||
/// // See KernelSpec.h for details on how the compiler can create a | ||
/// // MultiKernelLoaderSpec instance like SaxpyKernelLoaderSpec below. | ||
/// Expected<ccn::SaxpyKernel> MaybeKernel = | ||
/// ccn::SaxpyKernel::create(Executor, ccn::SaxpyKernelLoaderSpec); | ||
/// if (!MaybeKernel) { /* Handle error */ } | ||
/// ccn::SaxpyKernel SaxpyKernel = *MaybeKernel; | ||
/// Launch(SaxpyKernel, A, X, Y); | ||
/// \endcode | ||
/// | ||
/// With the compiler's help in specializing TypedKernel for each device kernel | ||
/// function (and generating a MultiKernelLoaderSpec instance for each kernel), | ||
/// the user can safely launch the device kernel from the host and get an error | ||
/// message at compile time if the argument types don't match the kernel | ||
/// parameter types. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef STREAMEXECUTOR_KERNEL_H | ||
#define STREAMEXECUTOR_KERNEL_H | ||
|
||
#include "streamexecutor/KernelSpec.h" | ||
#include "streamexecutor/Utils/Error.h" | ||
|
||
#include <memory> | ||
|
||
namespace streamexecutor { | ||
|
||
class KernelInterface; | ||
class StreamExecutor; | ||
|
||
/// The base class for device kernel functions. | ||
/// | ||
/// This class has no information about the types of the parameters taken by the | ||
/// kernel, so it is analogous to a void* pointer to a device function. | ||
/// | ||
/// See the TypedKernel class below for the subclass which does have information | ||
/// about parameter types. | ||
class KernelBase { | ||
public: | ||
KernelBase(KernelBase &&) = default; | ||
KernelBase &operator=(KernelBase &&) = default; | ||
~KernelBase(); | ||
|
||
/// Creates a kernel object from a StreamExecutor and a MultiKernelLoaderSpec. | ||
/// | ||
/// The StreamExecutor knows which platform it belongs to and the | ||
/// MultiKernelLoaderSpec knows how to find the kernel code for different | ||
/// platforms, so the combined information is enough to get the kernel code | ||
/// for the appropriate platform. | ||
static Expected<KernelBase> create(StreamExecutor *ParentExecutor, | ||
const MultiKernelLoaderSpec &Spec); | ||
|
||
const std::string &getName() const { return Name; } | ||
const std::string &getDemangledName() const { return DemangledName; } | ||
|
||
/// Gets a pointer to the platform-specific implementation of this kernel. | ||
KernelInterface *getImplementation() { return Implementation.get(); } | ||
|
||
private: | ||
KernelBase(StreamExecutor *ParentExecutor, const std::string &Name, | ||
const std::string &DemangledName, | ||
std::unique_ptr<KernelInterface> Implementation); | ||
|
||
StreamExecutor *ParentExecutor; | ||
std::string Name; | ||
std::string DemangledName; | ||
std::unique_ptr<KernelInterface> Implementation; | ||
|
||
KernelBase(const KernelBase &) = delete; | ||
KernelBase &operator=(const KernelBase &) = delete; | ||
}; | ||
|
||
/// A device kernel function with specified parameter types. | ||
template <typename... ParameterTs> class TypedKernel : public KernelBase { | ||
public: | ||
TypedKernel(TypedKernel &&) = default; | ||
TypedKernel &operator=(TypedKernel &&) = default; | ||
|
||
/// Parameters here have the same meaning as in KernelBase::create. | ||
static Expected<TypedKernel> create(StreamExecutor *ParentExecutor, | ||
const MultiKernelLoaderSpec &Spec) { | ||
auto MaybeBase = KernelBase::create(ParentExecutor, Spec); | ||
if (!MaybeBase) { | ||
return MaybeBase.takeError(); | ||
} | ||
TypedKernel Instance(std::move(*MaybeBase)); | ||
return std::move(Instance); | ||
} | ||
|
||
private: | ||
TypedKernel(KernelBase &&Base) : KernelBase(std::move(Base)) {} | ||
|
||
TypedKernel(const TypedKernel &) = delete; | ||
TypedKernel &operator=(const TypedKernel &) = delete; | ||
}; | ||
|
||
} // namespace streamexecutor | ||
|
||
#endif // STREAMEXECUTOR_KERNEL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
parallel-libs/streamexecutor/include/streamexecutor/StreamExecutor.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
//===-- StreamExecutor.h - The StreamExecutor class -------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// The StreamExecutor class which represents a single device of a specific | ||
/// platform. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef STREAMEXECUTOR_STREAMEXECUTOR_H | ||
#define STREAMEXECUTOR_STREAMEXECUTOR_H | ||
|
||
#include "streamexecutor/Utils/Error.h" | ||
|
||
namespace streamexecutor { | ||
|
||
class KernelInterface; | ||
|
||
class StreamExecutor { | ||
public: | ||
/// Gets the kernel implementation for the underlying platform. | ||
virtual Expected<std::unique_ptr<KernelInterface>> | ||
getKernelImplementation(const MultiKernelLoaderSpec &Spec) { | ||
// TODO(jhen): Implement this. | ||
return nullptr; | ||
} | ||
|
||
// TODO(jhen): Add other methods. | ||
}; | ||
|
||
} // namespace streamexecutor | ||
|
||
#endif // STREAMEXECUTOR_STREAMEXECUTOR_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//===-- Kernel.cpp - General kernel implementation ------------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// This file contains the implementation details for kernel types. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "streamexecutor/Kernel.h" | ||
#include "streamexecutor/Interfaces.h" | ||
#include "streamexecutor/StreamExecutor.h" | ||
|
||
#include "llvm/DebugInfo/Symbolize/Symbolize.h" | ||
|
||
namespace streamexecutor { | ||
|
||
KernelBase::KernelBase(StreamExecutor *ParentExecutor, const std::string &Name, | ||
const std::string &DemangledName, | ||
std::unique_ptr<KernelInterface> Implementation) | ||
: ParentExecutor(ParentExecutor), Name(Name), DemangledName(DemangledName), | ||
Implementation(std::move(Implementation)) {} | ||
|
||
KernelBase::~KernelBase() = default; | ||
|
||
Expected<KernelBase> KernelBase::create(StreamExecutor *ParentExecutor, | ||
const MultiKernelLoaderSpec &Spec) { | ||
auto MaybeImplementation = ParentExecutor->getKernelImplementation(Spec); | ||
if (!MaybeImplementation) { | ||
return MaybeImplementation.takeError(); | ||
} | ||
std::string Name = Spec.getKernelName(); | ||
std::string DemangledName = | ||
llvm::symbolize::LLVMSymbolizer::DemangleName(Name, nullptr); | ||
KernelBase Instance(ParentExecutor, Name, DemangledName, | ||
std::move(*MaybeImplementation)); | ||
return std::move(Instance); | ||
} | ||
|
||
} // namespace streamexecutor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.