Tfcompile nedir?
tfcompile
, önceden (AOT) TensorFlow grafiklerini çalıştırılabilir koda derleyen bağımsız bir araçtır. Toplam ikili boyutu azaltabilir ve ayrıca bazı çalışma zamanı ek yüklerini önleyebilir. Tipik bir tfcompile
kullanım durumu, bir çıkarım grafiğini mobil cihazlar için çalıştırılabilir koda derlemektir.
TensorFlow grafiği normalde TensorFlow çalışma zamanı tarafından yürütülür. Bu, grafikteki her düğümün yürütülmesi için bir miktar çalışma zamanı ek yüküne neden olur. Bu ayrıca, grafiğin kendisine ek olarak TensorFlow çalışma zamanı kodunun da bulunması gerektiğinden, daha büyük bir toplam ikili boyuta yol açar. tfcompile
tarafından üretilen yürütülebilir kod, TensorFlow çalışma zamanını kullanmaz ve yalnızca hesaplamada gerçekten kullanılan çekirdeklere bağımlılıklara sahiptir.
Derleyici, XLA çerçevesinin üzerine inşa edilmiştir. TensorFlow'u XLA çerçevesine köprüleyen kod, tensorflow / compiler altında bulunur.
Tfcompile ne yapar?
tfcompile
, TensorFlow besleme ve getirme kavramları tarafından tanımlanan bir alt tfcompile
alır ve bu alt grafiği uygulayan bir işlev oluşturur. feeds
, işlevin girdi bağımsız değişkenleridir ve fetches
işlevin çıktı bağımsız değişkenleridir. Tüm girişler, feed'ler tarafından tam olarak belirtilmelidir; elde edilen budanmış alt grafik Yer Tutucu veya Değişken düğümler içeremez. Tüm Yer Tutucular ve Değişkenlerin özet akışı olarak belirtilmesi yaygındır, bu da elde edilen alt grafiğin artık bu düğümleri içermemesini sağlar. Oluşturulan işlev, işlev imzasını dışa cc_library
bir başlık dosyası ve uygulamayı içeren bir nesne dosyasıyla bir cc_library
olarak paketlenir. Kullanıcı, oluşturulan işlevi uygun şekilde çağırmak için kod yazar.
Tfcompile kullanma
Bu bölüm, bir yürütülebilir ikili üretilmesi için yüksek düzeyde adımları ayrıntılı tfcompile
bir TensorFlow alt grafiği ile ilgili. Adımlar:
- Adım 1: Alt grafiği derlemek için yapılandırın
- Adım 2: Alt grafiği derlemek için
tf_library
yapı makrosunu kullanın - Adım 3: Alt grafiği çağırmak için kod yazın
- 4. Adım: Son ikili dosyayı oluşturun
Adım 1: Alt grafiği derlemek için yapılandırın
Oluşturulan işlev için giriş ve çıkış argümanlarına karşılık gelen feed'leri ve getirmeleri tanımlayın. Sonra yapılandırmak feeds
ve fetches
bir de tensorflow.tf2xla.Config
proto.
# Each feed is a positional input argument for the generated function. The order
# of each entry matches the order of each input argument. Here “x_hold” and “y_hold”
# refer to the names of placeholder nodes defined in the graph.
feed {
id { node_name: "x_hold" }
shape {
dim { size: 2 }
dim { size: 3 }
}
}
feed {
id { node_name: "y_hold" }
shape {
dim { size: 3 }
dim { size: 2 }
}
}
# Each fetch is a positional output argument for the generated function. The order
# of each entry matches the order of each output argument. Here “x_y_prod”
# refers to the name of a matmul node defined in the graph.
fetch {
id { node_name: "x_y_prod" }
}
Adım 2: Alt grafiği derlemek için tf_library yapı makrosunu kullanın
Bu adım, grafiği tf_library
oluşturma makrosunu kullanarak bir cc_library
dönüştürür. cc_library
, oluşturulan koda erişim sağlayan bir başlık dosyası ile birlikte grafikten oluşturulan kodu içeren bir nesne dosyasından oluşur. tf_library
kullandığı tfcompile
yürütülebilir koduna TensorFlow grafik derlemek.
load("//tensorflow/compiler/aot:tfcompile.bzl", "tf_library")
# Use the tf_library macro to compile your graph into executable code.
tf_library(
# name is used to generate the following underlying build rules:
# <name> : cc_library packaging the generated header and object files
# <name>_test : cc_test containing a simple test and benchmark
# <name>_benchmark : cc_binary containing a stand-alone benchmark with minimal deps;
# can be run on a mobile device
name = "test_graph_tfmatmul",
# cpp_class specifies the name of the generated C++ class, with namespaces allowed.
# The class will be generated in the given namespace(s), or if no namespaces are
# given, within the global namespace.
cpp_class = "foo::bar::MatMulComp",
# graph is the input GraphDef proto, by default expected in binary format. To
# use the text format instead, just use the ‘.pbtxt’ suffix. A subgraph will be
# created from this input graph, with feeds as inputs and fetches as outputs.
# No Placeholder or Variable ops may exist in this subgraph.
graph = "test_graph_tfmatmul.pb",
# config is the input Config proto, by default expected in binary format. To
# use the text format instead, use the ‘.pbtxt’ suffix. This is where the
# feeds and fetches were specified above, in the previous step.
config = "test_graph_tfmatmul.config.pbtxt",
)
Bu örnek, çalışma için GraphDef proto (test_graph_tfmatmul.pb) üretmek için make_test_graphs.py ve --out_dir bayrağıyla çıkış konumunu belirtin.
Tipik grafikler, eğitim yoluyla öğrenilen ağırlıkları temsil eden Variables
içerir, ancak tfcompile
, Variables
içeren bir alt grafiği tfcompile
. Freeze_graph.py aracı, bir kontrol noktası dosyasında saklanan değerleri kullanarak değişkenleri sabitlere dönüştürür. Bir kolaylık olarak, tf_library
makrosu, aracı çalıştıran freeze_checkpoint
argümanını destekler. Daha fazla örnek için tensorflow / compiler / aot / testing / BUILD sayfasına bakın .
Derlenen alt grafikte gösterilen sabitler, doğrudan üretilen koda derlenir. Sabitleri derlemek yerine oluşturulan işleve geçirmek için, basitçe besleme olarak aktarın.
tf_library
derleme makrosu ile ilgili ayrıntılar için, bkz. Tfcompile.bzl .
Temel tfcompile
aracı hakkında ayrıntılar için, bkz. Tfcompile_main.cc .
Adım 3: Alt grafiği çağırmak için kod yazın
Bu adım, üretilen kodu çağırmak için önceki adımda tf_library
yapı makrosu tarafından oluşturulan başlık dosyasını ( test_graph_tfmatmul.h
) kullanır. Başlık dosyası, yapı paketine karşılık gelen bazel-bin
dizininde bulunur ve tf_library
yapı makrosundaki ad özniteliğine göre adlandırılır. Örneğin, için oluşturulmuş başlık test_graph_tfmatmul
olacaktır test_graph_tfmatmul.h
. Aşağıda, oluşturulan şeyin kısaltılmış bir versiyonu bulunmaktadır. bazel-bin
oluşturulan dosya ek yararlı yorumlar içerir.
namespace foo {
namespace bar {
// MatMulComp represents a computation previously specified in a
// TensorFlow graph, now compiled into executable code.
class MatMulComp {
public:
// AllocMode controls the buffer allocation mode.
enum class AllocMode {
ARGS_RESULTS_AND_TEMPS, // Allocate arg, result and temp buffers
RESULTS_AND_TEMPS_ONLY, // Only allocate result and temp buffers
};
MatMulComp(AllocMode mode = AllocMode::ARGS_RESULTS_AND_TEMPS);
~MatMulComp();
// Runs the computation, with inputs read from arg buffers, and outputs
// written to result buffers. Returns true on success and false on failure.
bool Run();
// Arg methods for managing input buffers. Buffers are in row-major order.
// There is a set of methods for each positional argument.
void** args();
void set_arg0_data(float* data);
float* arg0_data();
float& arg0(size_t dim0, size_t dim1);
void set_arg1_data(float* data);
float* arg1_data();
float& arg1(size_t dim0, size_t dim1);
// Result methods for managing output buffers. Buffers are in row-major order.
// Must only be called after a successful Run call. There is a set of methods
// for each positional result.
void** results();
float* result0_data();
float& result0(size_t dim0, size_t dim1);
};
} // end namespace bar
} // end namespace foo
Oluşturulan C ++ sınıfı olarak adlandırılır MatMulComp
içinde foo::bar
oldu, çünkü ad cpp_class
belirtilen tf_library
makro. Oluşturulan tüm sınıfların benzer bir API'si vardır, tek fark arg ve sonuç tamponlarını işleme yöntemidir. Bu yöntemler, feed
ve tf_library
makrosuna fetch
bağımsız değişkenleri tarafından belirtilen arabelleklerin sayısına ve türlerine göre farklılık gösterir.
Üç oluşturulan sınıf içindeki yönetilen tampon türleri vardır args
giriş temsil results
ürünleri yansıtan ve temps
hesaplama yapmak için dahili olarak kullanılan geçici tamponlar temsil eder. Varsayılan olarak, oluşturulan sınıfın her bir örneği tüm bu arabellekleri sizin için ayırır ve yönetir. AllocMode
yapıcı bağımsız değişkeni bu davranışı değiştirmek için kullanılabilir. Tüm arabellekler 64 baytlık sınırlarla hizalanır.
Oluşturulan C ++ sınıfı, XLA tarafından üretilen düşük seviyeli kodun etrafındaki bir sarmalayıcıdır.
tfcompile_test.cc
dayalı olarak oluşturulan işlevi çağırma tfcompile_test.cc
:
#define EIGEN_USE_THREADS
#define EIGEN_USE_CUSTOM_THREAD_POOL
#include <iostream>
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#include "tensorflow/compiler/aot/tests/test_graph_tfmatmul.h" // generated
int main(int argc, char** argv) {
Eigen::ThreadPool tp(2); // Size the thread pool as appropriate.
Eigen::ThreadPoolDevice device(&tp, tp.NumThreads());
foo::bar::MatMulComp matmul;
matmul.set_thread_pool(&device);
// Set up args and run the computation.
const float args[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
std::copy(args + 0, args + 6, matmul.arg0_data());
std::copy(args + 6, args + 12, matmul.arg1_data());
matmul.Run();
// Check result
if (matmul.result0(0, 0) == 58) {
std::cout << "Success" << std::endl;
} else {
std::cout << "Failed. Expected value 58 at 0,0. Got:"
<< matmul.result0(0, 0) << std::endl;
}
return 0;
}
4. Adım: Son ikili dosyayı oluşturun
Bu adım, son bir ikili oluşturmak için 2. adımda tf_library
tarafından oluşturulan kitaplığı ve 3. adımda yazılan kodu birleştirir. Aşağıda örnek bir bazel
BUILD dosyası bulunmaktadır.
# Example of linking your binary
# Also see //tensorflow/compiler/aot/tests/BUILD
load("//tensorflow/compiler/aot:tfcompile.bzl", "tf_library")
# The same tf_library call from step 2 above.
tf_library(
name = "test_graph_tfmatmul",
...
)
# The executable code generated by tf_library can then be linked into your code.
cc_binary(
name = "my_binary",
srcs = [
"my_code.cc", # include test_graph_tfmatmul.h to access the generated header
],
deps = [
":test_graph_tfmatmul", # link in the generated object file
"//third_party/eigen3",
],
linkopts = [
"-lpthread",
]
)