MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / ComputeMklSlice

Method ComputeMklSlice

tensorflow/core/kernels/mkl_slice_op.cc:357–482  ·  view source on GitHub ↗

Slice op implemented using MKL-DNN APIs.

Source from the content-addressed store, hash-verified

355 private:
356 // Slice op implemented using MKL-DNN APIs.
357 void ComputeMklSlice(OpKernelContext* context,
358 const gtl::InlinedVector<int64, 4>& begin,
359 const gtl::InlinedVector<int64, 4>& size) {
360 try {
361 // OneDNN API usage below is guided by description at:
362 // https://github.com/01org/mkl-dnn/issues/69
363 //
364 // Relevant part of the description is copied below:
365 //
366 // Let's say you want to copy a part of memory into another buffer (and
367 // probably change the format). Then your steps are:
368 //
369 // 1. create memory primitive descriptor in_mem_pd and memory primitive
370 // in_mem_p for the entire source data. create view primitive
371 // descriptor in_submem_pd based on in_mem_pd, initial offsets,
372 // and sub-sizes
373 // 2. create memory primitive descriptor out_mem_pd and memory primitive
374 // out_mem_p for the output (the logical sizes should match sub-sizes
375 // used in step 1, but the format might be arbitrary)
376 // 3. create reorder primitive descriptor reorder_pd based on in_submem_pd
377 // and out_mem_pd. create reorder primitive itself based on reorder_pd,
378 // in_mem_p, and out_mem_p.
379 //
380 // Please notice that there is no view primitive. There is only view
381 // primitive descriptor. And the reorder uses source memory as input but
382 // traverses it according to a view in_submem_pd.
383
384 auto cpu_engine = engine(ENGINE_CPU, 0);
385 MklDnnData<T> src(&cpu_engine);
386 MklDnnData<T> output(&cpu_engine);
387
388 // Populate offsets and sizes in memory::dims format based on vector.
389 memory::dims begin_dims = {};
390 begin_dims.resize(begin.size());
391 for (size_t i = 0; i < begin.size(); ++i) begin_dims[i] = begin[i];
392 memory::dims size_dims = {};
393 bool empty = false;
394 size_dims.resize(size.size());
395 for (size_t i = 0; i < size.size(); ++i) {
396 size_dims[i] = size[i];
397 if (size_dims[i] == 0) empty = true;
398 }
399
400 Tensor* output_tensor = nullptr;
401 MklDnnShape output_mkl_shape;
402
403 // If no dimension is selected in slice, the result should be empty.
404 // Just return an empty output tensor, and a dummy OneDNN-shape tensor.
405 if (empty) { // for empty dims
406 auto shape_to = MklDnnDimsToTFShape(size_dims);
407 AllocateOutputSetMklShape(context, 0, &output_tensor, shape_to,
408 output_mkl_shape);
409 return;
410 }
411
412 // Step 1 (as per above description) - Create memory for user data.
413 // We use blocked format here to describe input tensor.
414 const Tensor& input_tensor = MklGetInput(context, 0);

Callers

nothing calls this directly

Calls 15

MklDnnDimsToTFShapeFunction · 0.85
GetMklShapeFunction · 0.85
MklDnnDimsInNCHWFunction · 0.85
MklDnnDimsInNCDHWFunction · 0.85
CalculateTFStridesFunction · 0.85
TFShapeToMklDnnDimsFunction · 0.85
GetFunction · 0.85
CreateStreamFunction · 0.85
to_stringFunction · 0.85
IsMklTensorMethod · 0.80

Tested by

no test coverage detected