2016-05-19 4 views
0

In tensorflow registrieren I ein op etwa so:Wie kann man im Tensorflow auf einen skalaren Tensorwert zugreifen, bevor er auf die GPU übertragen wird?

REGISTER_OP("RimeBSqrt") 
    .Input("stokes: FT") 
    .Input("alpha: FT") 
    .Input("frequency: FT") 
    .Input("ref_freq: FT") 
    .Output("b_sqrt: CT") 
    .Attr("FT: {float, double} = DT_FLOAT") 
    .Attr("CT: {complex64, complex128} = DT_COMPLEX64"); 

Alle oben genannten Eingänge sind Tensoren, aber ref_freq ein Skalar oder 0-D-Tensors. Im Compute() Methode meiner CPU kernel ich folgendes tun kann die skalare zu extrahieren:

const Tensor & in_ref_freq = context->input(3); 
FT ref_freq = in_ref_freq.tensor<FT, 1>()(0); 

die gleiche Art von Code erzeugt jedoch einen segfault im Compute() Methode meiner GPU Kernel , weil die CPU jetzt versucht, auf einen Speicherblock auf dem GPU-Gerät zuzugreifen. Gibt es einen Wert, der diesen skalaren Wert abfängt, bevor er in die GPU gesendet wird? Ich möchte vermeiden die folgende zusätzliche Ebene der Speicher indirection in einen CUDA Kernel:

template <typename FT> 
__global__ void kernel(..., FT * ref_freq, ...) 
{ 
    FT value = ref_freq[0]; 
} 

Ich glaube nicht, Attr der Ansatz für ref_freq zu verwenden ist, da sie veränderbar ist, konfigurierbaren Wert.

  1. CPU Tensorflow Kernelcode ist here.
  2. GPU Tensorflow Kernel-Code ist here.
  3. Python variable Setup-Code ist here

Antwort

3

Sie können angeben, dass ein oder mehrere der Eingänge (oder Ausgänge) einer TensorFlow OpKernel sind in „Host-Speicher“, die man den Wert in der für den Zugriff ermöglicht Compute() Methode. Um dies zu tun, würden Sie Ihren REGISTER_KERNEL_BUILDER() Anruf ändern hinzufügen, um eine .HostMemory("ref_freq") Anweisung:

REGISTER_KERNEL_BUILDER(
    Name("RimeBSqrt") 
    .Device(tensorflow::DEVICE_GPU) 
    .TypeConstraint<float>("FT") 
    .TypeConstraint<tensorflow::complex64>("CT") 
    .HostMemory("ref_freq"), 
    RimeBSqrt<tensorflow::GPUDevice, float, tensorflow::complex64>); 
+0

Dank! Verhindert die HostMemory-Anweisung auch die Übertragung von ref_freq an die GPU? – Simon

+0

Die HostMemory-Anweisung verhindert, dass sie automatisch von der Laufzeitumgebung kopiert wird. Ich bin keineswegs ein CUDA-Experte, aber ich denke, Sie würden den 'OpKernel' modifizieren, um den' float'-Wert aus dem Tensor zu extrahieren und ihn als 'float'-Argument an den CUDA-Kernel zu übergeben (wie bei der 'int' Argumente [hier] (https://github.com/ska-sa/montblanc/blob/53edf2ba505e4b5b10ae89e187c4f11d1e7072db/montblanc/tensorflow/rime_ops/b_sqrt_op_gpu.h#L71)). – mrry

+0

Großartig, genau das habe ich gesucht. – Simon

Verwandte Themen