mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-20 21:14:14 +08:00
Summary: Hi guys, I'd like to build Caffe2 with more supported options in Windows with Microsoft Visual Studios. This is the first pull request. Running scripts/build_windows_shared.bat is able to build Caffe2 with both CMAKE_BUILD_TYPE=Debug and CMAKE_BUILD_TYPE=Release with Visual Studio 14 2015. CUDA is 9.0, cudnn is 7.0.5, glog, gflags and lmdb are supported on my system. Python is 3.5, Detectron works from python interface as well. It was even possible to debug detectron code and step into caffe2_gpu.dll with pdbs built. What is disappointing, that c10/experimental ops don't build with this Visual Studio generator, I added special option INCLUDE_EXPERIMENTAL_C10_OPS (default ON) to deal with it in build_windows_shared.bat. After this pull request the next step is to add Visual Studio 2017 support in the script. Pull Request resolved: https://github.com/pytorch/pytorch/pull/13550 Reviewed By: ezyang Differential Revision: D13042597 Pulled By: orionr fbshipit-source-id: f313f909f599cd582a1d000eff766eef3a9fc4fc
136 lines
3.7 KiB
C++
136 lines
3.7 KiB
C++
|
|
#include "../core/GLFilter.h"
|
|
#include "../core/GLImage.h"
|
|
#include "../core/ImageAllocator.h"
|
|
|
|
#include "caffe2/core/operator.h"
|
|
#include "caffe2/core/timer.h"
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
typedef enum { Sigmoid, Tanh } OpType;
|
|
|
|
class GLSigmoid : public GLFilter {
|
|
public:
|
|
binding* inputData;
|
|
binding* outputSize;
|
|
|
|
GLSigmoid(OpType opType)
|
|
: GLFilter(
|
|
"GLSigmoid",
|
|
vertex_shader,
|
|
fragment_shader,
|
|
{BINDING(outputSize), BINDING(inputData)},
|
|
{/* no uniform blocks */},
|
|
{/* no attributes */},
|
|
{{"SIGMOID", c10::to_string(opType == Sigmoid)},
|
|
{"TANH", c10::to_string(opType == Tanh)}}) {}
|
|
|
|
template <typename T>
|
|
void sigmoid(const GLImageVector<T>& input_images, const GLImageVector<T>& output_images);
|
|
|
|
static const char* fragment_shader;
|
|
};
|
|
|
|
// MARK: GLSL
|
|
|
|
const char* GLSigmoid::fragment_shader = R"GLSL(#version 300 es
|
|
#define SIGMOID $(SIGMOID)
|
|
#define TANH $(TANH)
|
|
|
|
precision mediump float;
|
|
precision mediump int;
|
|
|
|
in highp vec2 v_texCoord;
|
|
|
|
uniform ivec2 outputSize;
|
|
|
|
TEXTURE_INPUT(inputData);
|
|
TEXTURE_OUTPUT(0, outputData);
|
|
|
|
void main() {
|
|
ivec2 texelCoord = ivec2(v_texCoord * vec2(outputSize));
|
|
vec4 value = TEXTURE_LOAD(inputData, ivec2(texelCoord));
|
|
#if SIGMOID
|
|
value = vec4(1.0) / (vec4(1.0) + exp(-value));
|
|
outputData = TEXTURE_STORE(value);
|
|
#elif TANH
|
|
value = tanh(value);
|
|
outputData = TEXTURE_STORE(value);
|
|
#endif
|
|
}
|
|
|
|
)GLSL";
|
|
|
|
template <typename T>
|
|
void GLSigmoid::sigmoid(const GLImageVector<T>& input_images,
|
|
const GLImageVector<T>& output_images) {
|
|
for (int i = 0; i < input_images.size(); i++) {
|
|
auto input_image = input_images[i];
|
|
auto output_image = output_images[i];
|
|
int input_slices = input_image->slices;
|
|
int output_slices = output_image->slices;
|
|
|
|
for (int is = 0; is < input_slices; is++) {
|
|
run(std::vector<texture_attachment>({{input_image->textures[is], inputData}}),
|
|
{output_image->textures.begin() + is, output_image->textures.begin() + is + 1},
|
|
[&]() { glUniform2i(outputSize->location, output_image->width, output_image->height); },
|
|
output_image->width,
|
|
output_image->height);
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace caffe2 {
|
|
template <typename T, OpType opType>
|
|
class OpenGLSigmoidOp final : public Operator<CPUContext>, ImageAllocator<T> {
|
|
public:
|
|
OpenGLSigmoidOp(const OperatorDef& operator_def, Workspace* ws)
|
|
: Operator<CPUContext>(operator_def, ws) {}
|
|
|
|
bool RunOnDevice() override {
|
|
const GLImageVector<T>& input = Inputs()[0]->template Get<GLImageVector<T>>();
|
|
const int num_images = input.size();
|
|
const int input_channels = input.channels();
|
|
const int input_width = input.width();
|
|
const int input_height = input.height();
|
|
|
|
const int output_channels = input_channels;
|
|
const int output_width = input_width;
|
|
const int output_height = input_height;
|
|
|
|
int is_last = OperatorBase::GetSingleArgument<int>("is_last", 0);
|
|
|
|
GLImageVector<T>* output = ImageAllocator<T>::newImage(
|
|
num_images, output_width, output_height, output_channels, is_last);
|
|
|
|
if (!_sigmoid) {
|
|
_sigmoid.reset(new GLSigmoid(opType));
|
|
}
|
|
|
|
_sigmoid->sigmoid(input, *output);
|
|
|
|
Outputs()[0]->Reset(output);
|
|
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<GLSigmoid> _sigmoid;
|
|
};
|
|
|
|
REGISTER_CPU_OPERATOR(OpenGLSigmoid, OpenGLSigmoidOp<float16_t, Sigmoid>);
|
|
OPERATOR_SCHEMA(OpenGLSigmoid)
|
|
.NumInputs(1)
|
|
.NumOutputs(1)
|
|
.AllowInplace({{0, 0}})
|
|
.IdenticalTypeAndShape();
|
|
|
|
REGISTER_CPU_OPERATOR(OpenGLTanh, OpenGLSigmoidOp<float16_t, Tanh>);
|
|
OPERATOR_SCHEMA(OpenGLTanh)
|
|
.NumInputs(1)
|
|
.NumOutputs(1)
|
|
.AllowInplace({{0, 0}})
|
|
.IdenticalTypeAndShape();
|
|
} // namespace caffe2
|