Ich versuche, TensorFlow lose ein neues Op nach this Dokument hinzuzufügen. Der Unterschied ist, dass ich versuche, einen GPU-basierten Op zu implementieren. Die Op, die ich hinzufügen möchte, ist die cuda op von here (cuda_op.py, cuda_op_kernel.cc, cuda_op_kernel.cu.cc). . Ich versuche, diese außerhalb von tensorflow zu kompilieren und die Verwendung tf.load_op_library
sie in ziehen, habe ich einige Änderungen vorgenommen hier so sind meine Dateien:Hinzufügen einer GPU Op in Tensorflow
cuda_op_kernel.cc
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/framework/op_kernel.h"
using namespace tensorflow; // NOLINT(build/namespaces)
REGISTER_OP("AddOne")
.Input("input: int32")
.Output("output: int32")
.SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) {
c->set_output(0, c->input(0));
return Status::OK();
});
void AddOneKernelLauncher(const int* in, const int N, int* out);
class AddOneOp : public OpKernel {
public:
explicit AddOneOp(OpKernelConstruction* context) : OpKernel(context) {}
void Compute(OpKernelContext* context) override {
// Grab the input tensor
const Tensor& input_tensor = context->input(0);
auto input = input_tensor.flat<int32>();
// Create an output tensor
Tensor* output_tensor = NULL;
OP_REQUIRES_OK(context, context->allocate_output(0, input_tensor.shape(),
&output_tensor));
auto output = output_tensor->template flat<int32>();
// Set all but the first element of the output tensor to 0.
const int N = input.size();
// Call the cuda kernel launcher
AddOneKernelLauncher(input.data(), N, output.data());
}
};
REGISTER_KERNEL_BUILDER(Name("AddOne").Device(DEVICE_GPU), AddOneOp);
cuda_op_kernel.cu
#define EIGEN_USE_GPU
#include <cuda.h>
#include <stdio.h>
__global__ void AddOneKernel(const int* in, const int N, int* out) {
for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < N;
i += blockDim.x * gridDim.x) {
out[i] = in[i] + 1;
}
}
void AddOneKernelLauncher(const int* in, const int N, int* out) {
AddOneKernel<<<32, 256>>>(in, N, out);
cudaError_t cudaerr = cudaDeviceSynchronize();
if (cudaerr != cudaSuccess)
printf("kernel launch failed with error \"%s\".\n", cudaGetErrorString(cudaerr));
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
#found from running python -c 'import tensorflow as tf; print(tf.sysconfig.get_include())'
include_directories(/usr/local/lib/python3.5/dist-packages/tensorflow/include)
find_package(CUDA)
#set flags based on tutorial
set (CMAKE_CXX_FLAGS "--std=c++11 -fPIC -O2 -D_GLIBCXX_USE_CXX11_ABI=0")
#pass flags to c++ compiler
SET(CUDA_PROPAGATE_HOST_FLAGS ON)
#create library
cuda_add_library(
cuda_op SHARED
src/cuda_op_kernel.cu
src/cuda_op_kernel.cc
OPTIONS -gencode=arch=compute_20,code=sm_20)
#copy test file to build folder
configure_file(src/test.py test.py COPYONLY)
test.py
import tensorflow as tf
mod = tf.load_op_library('./libcuda_op.so')
with tf.Session() as sess:
start = [5,4,3,2,1]
print(start)
print(mod.add_one(start).eval())
Ich bin in der Lage test.py
erfolgreich zu kompilieren und ausführen, aber der Ausgang ist immer [0 0 0 0 0]
. Wenn ich AddOneKernel<<<32, 256>>>(in, N, out);
durch for (int i = 0; i < N; i++) out[i] = in[i] + 1;
und DEVICE_GPU
durch DEVICE_CPU
ersetze, gibt das op die richtigen Werte aus [6 5 4 3 2]
(mit genau demselben CMakeList.txt
).
Haben Sie eine Idee, wie Sie die richtigen Werte erhalten?
Ich habe versucht, Ihrem Beispiel zu folgen, aber wenn Sie make ausführen, beschweren Sie sich über den Tensorflow-Namespace ?! Was könnte das Problem sein? – Essa
Ein bisschen spät zu antworten, aber Sie sollten eine neue Frage dafür erstellen. – McAngus