create my own resource types (tf.resource) - tensorflow

My current code:
// For Eigen::ThreadPoolDevice.
#define EIGEN_USE_THREADS 1
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/resource_mgr.h"
#include "tensorflow/core/framework/resource_op_kernel.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/platform/mutex.h"
#include "tensorflow/core/platform/types.h"
using namespace tensorflow;
REGISTER_OP("ArrayContainerCreate")
.Attr("T: type")
.Attr("container: string = ''")
.Attr("shared_name: string = ''")
.Output("resource: resource")
.SetIsStateful()
.SetShapeFn(shape_inference::ScalarShape)
.Doc(R"doc(Array container, random index access)doc");
REGISTER_OP("ArrayContainerGetSize")
.Input("handle: resource")
.Output("out: int32")
.SetShapeFn(shape_inference::ScalarShape)
;
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/resource_mgr.h
struct ArrayContainer : public ResourceBase {
ArrayContainer(const DataType& dtype) : dtype_(dtype) {}
string DebugString() override { return "ArrayContainer"; }
int64 MemoryUsed() const override { return 0; };
mutex mu_;
const DataType dtype_;
int32 get_size() {
mutex_lock l(mu_);
return (int32) 42;
}
};
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/resource_op_kernel.h
class ArrayContainerCreateOp : public ResourceOpKernel<ArrayContainer> {
public:
explicit ArrayContainerCreateOp(OpKernelConstruction* context) : ResourceOpKernel(context) {
OP_REQUIRES_OK(context, context->GetAttr("T", &dtype_));
}
private:
virtual bool IsCancellable() const { return false; }
virtual void Cancel() {}
Status CreateResource(ArrayContainer** ret) override EXCLUSIVE_LOCKS_REQUIRED(mu_) {
*ret = new ArrayContainer(dtype_);
if(*ret == nullptr)
return errors::ResourceExhausted("Failed to allocate");
return Status::OK();
}
Status VerifyResource(ArrayContainer* ar) override {
if(ar->dtype_ != dtype_)
return errors::InvalidArgument("Data type mismatch: expected ", DataTypeString(dtype_),
" but got ", DataTypeString(ar->dtype_), ".");
return Status::OK();
}
DataType dtype_;
};
REGISTER_KERNEL_BUILDER(Name("ArrayContainerCreate").Device(DEVICE_CPU), ArrayContainerCreateOp);
class ArrayContainerGetSizeOp : public OpKernel {
public:
using OpKernel::OpKernel;
void Compute(OpKernelContext* context) override {
ArrayContainer* ar;
OP_REQUIRES_OK(context, GetResourceFromContext(context, "handle", &ar));
core::ScopedUnref unref(ar);
int32 size = ar->get_size();
Tensor* tensor_size = nullptr;
OP_REQUIRES_OK(context, context->allocate_output(0, TensorShape({}), &tensor_size));
tensor_size->flat<int32>().setConstant(size);
}
};
REGISTER_KERNEL_BUILDER(Name("ArrayContainerGetSize").Device(DEVICE_CPU), ArrayContainerGetSizeOp);
I compile that. Note that I first got some undefined symbol: _ZN6google8protobuf8internal26fixed_address_empty_stringE error but I resolved that by adding these additional compiler flags:
from google.protobuf.pyext import _message as msg
lib = msg.__file__
extra_compiler_flags = [
"-Xlinker", "-rpath", "-Xlinker", os.path.dirname(lib),
"-L", os.path.dirname(lib), "-l", ":" + os.path.basename(lib)]
I read about that here.
Then I load that as a module via tf.load_op_library.
Then, I have this Python code:
handle = mod.array_container_create(T=tf.int32)
size = mod.array_container_get_size(handle=handle)
When I try to evaluate size, I get the error:
InvalidArgumentError (see above for traceback): Trying to access resource located in device 14ArrayContainer from device /job:localhost/replica:0/task:0/cpu:0
[[Node: ArrayContainerGetSize = ArrayContainerGetSize[_device="/job:localhost/replica:0/task:0/cpu:0"](array_container)]]
The device name (14ArrayContainer) somehow seem to be messed up. Why is that? What is the problem with the code?
For some more testing, I added this additional code in the ArrayContainerCreateOp:
ResourceHandle rhandle = MakeResourceHandle<ArrayContainer>(context, cinfo_.container(), cinfo_.name());
printf("created. device: %s\n", rhandle.device().c_str());
printf("container: %s\n", rhandle.container().c_str());
printf("name: %s\n", rhandle.name().c_str());
printf("actual device: %s\n", context->device()->attributes().name().c_str());
printf("actual name: %s\n", cinfo_.name().c_str());
This gives me the output:
created. device: 14ArrayContainer
container: 14ArrayContainer
name: 14ArrayContainer
actual device: /job:localhost/replica:0/task:0/cpu:0
actual name: _2_array_container
So clearly, there is some of the problem.
This looks like something is messed up with the protobuf? Maybe I am linking the wrong lib? But I have not found which lib to link instead.
(I also posted an issue about this here.)

That is upstream bug 10950, which should be fixed in TensorFlow 1.2.2.

Related

Simple parsing to a tuple fails

Why does this not compile? The marked line gives me: "static assertion failed: The parser expects tuple-like attribute type". I would think that an std::tuple were the essence of "tuple-like"?
#include <string>
#include <tuple>
#include <boost/spirit/home/x3.hpp>
void parseInteger(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
int result;
x3::parse(iter, end_iter, x3::int_, result);
}
void parseIntegerAndDouble(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
std::tuple<int, double> result;
x3::parse(iter, end_iter, x3::int_ >> ' ' >> x3::double_, result); //Compile error!
}
int main(int, char **)
{
parseInteger("567");
parseIntegerAndDouble("321 3.1412");
return 0;
}
The trick is to include two additional header files:
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/std_tuple.hpp>
This is a bit more magical than I like, but I've got a feeling I really don't want to know how this works!

passing a class variable to API function

I want to track a global variable that I am passing into an API function. I found that one could do it using a class:
template <class T>
class MonitoredVariable
{
public:
MonitoredVariable() {}
MonitoredVariable(const T& value) : m_value(value) {}
//T operator T() const { return m_value; }
const MonitoredVariable& operator = (const T& value)
{
PlugIn::gResultOut << "value changed " << std::endl;
m_value = value;
return *this;
}
private:
T m_value;
};
The API function takes variables as
bool APIFunction(double time, bool *is_done, double *fraction_done);
The following gives me an error:
ImagePtr Im;
bool is_done;
MonitoredVariable<double*> fraction_done;
bool frameready = Im->APIFunction(2.1, is_done, fraction_done);
ERROR:
error C2664: cannot convert argument 3 from 'MonitoredVariable<double *>' to 'double *'
what would I have to change here?
thx!
I'm not really sure if this is what you want:
#include <iostream>
using namespace std;
template <class T>
class MonitoredVariable
{
public:
MonitoredVariable() {}
MonitoredVariable(const T& value) : m_value(value) {}
//T operator T() const { return m_value; }
const MonitoredVariable& operator = (const T& value)
{
//PlugIn::gResultOut << "value changed " << std::endl;
m_value = value.m_value;
return *this;
}
void printValue() {
std::cout << m_value;
}
T& getValue() {
return m_value;
}
private:
T m_value;
};
bool func(double firstDouble, bool *is_done, double* fraction_done) {
// do stuff
*fraction_done = firstDouble + (40.23 * 5);
*is_done = true;
return true;
}
int main()
{
bool is_done = true;
MonitoredVariable<double> fraction_done;
func(2.10, &is_done, &fraction_done.getValue());
fraction_done.printValue();
return 0;
}
So basically we have a Class called MonitoredVariable which has a variable called m_value. I'm not really sure why you wanted it to be a pointer, because we can also take the address of a normal double variable.
In the following it makes perhaps more sense what I want to achieve. I want to input a class variable into an API function and monitor the variable in real time. This value goes from zero to 1 every 3 ms or so. Yet I try to avoid using while loop and track it within the class with overloaded = operator.
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <future>
using namespace std;
template <class T>
class MonitoredVariable
{
public:
MonitoredVariable() {}
MonitoredVariable(const T& value) : m_value(value) {}
void printValue() {
std::cout << m_value;
}
const MonitoredVariable& operator = (const T& value)
{
m_value = value.m_value;
if(m_value> 0.8) std::cout << m_value; // *THIS NEVER GETS PRINTED!!!*
return *this;
}
T& getValue() {
return m_value;
}
private:
T m_value;
};
bool func(bool *is_done, double* fraction_done) {
unsigned long c = 1;
while (*is_done)
{
*fraction_done = (double) 0.01*c;
this_thread::sleep_for(chrono::milliseconds(10));
c++;
if (*fraction_done >= 1) *is_done = false;
}
return true;
}
int main()
{
bool is_done = true;
MonitoredVariable<double> *MonitoredVariablePtr = new MonitoredVariable<double>();
std::future<bool> fu = std::async(std::launch::async,func, &is_done, &MonitoredVariablePtr->getValue());
// IF I UNCOMMENT THIS, IT PRINTS...
/*
while(is_done)
{
if(MonitoredVariablePtr->getValue() > 0.8) MonitoredVariablePtr->printValue();
}
*/
return 0;
}
Why does not the (if(m_value> 0.8) std::cout << m_value) line within the class never gets printed when the value is updated?
THX!

How to io_control of boost library socket with customized command

I' trying to make an identical function to "ioctl" in c++ style using boost library.
Here is my "c" style code:
int sockfd;
char * id;
struct iwreq wreq;
memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
exit(1);
}
printf("Socket opened successfully \n");
id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;
if (ioctl(sockfd, SIOCGIWESSID, &wreq)) {
fprintf(stderr, "Get ESSID ioctl failed \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description : %s\n",strerror(errno));
exit(2);
}
printf("IOCTL Successfull\n");
printf("ESSID is %s\n", wreq.u.essid.pointer);
I found some relevant example, but I'm not clear how to use it correctly. example
Main function:
boost::asio::ip::udp::socket socket(io_service);
struct iwreq wreq
memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);
id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;
boost::asio::detail::io_control::myCommand command;
command.set(&wreq);
boost::system::error_code ec;
socket.io_control(command, ec);
if (ec)
{
// An error occurred.
}
Custom command:
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/asio/detail/socket_types.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
namespace io_control {
// I/O control command for getting number of bytes available.
class myCommand
{
public:
// Default constructor.
myCommand()
: value_(0)
{
}
// Get the name of the IO control command.
int name() const
{
return static_cast<int>(SIOCGIWESSID);
}
// Set the value of the I/O control command.
void set(struct iwreq* value)
{
value_ = static_cast<detail::ioctl_arg_type>(value);
}
// Get the current value of the I/O control command.
std::size_t get() const
{
return static_cast<struct iwreq*>(value_);
}
// Get the address of the command data.
detail::ioctl_arg_type* data()
{
return &value_;
}
// Get the address of the command data.
const detail::ioctl_arg_type* data() const
{
return &value_;
}
private:
detail::ioctl_arg_type value_;
};
} // namespace io_control
} // namespace detail
} // namespace asio
} // namespace boost
However, the code does not work.
If you have any example code or solution, please let me know.
Thank you.

System::String^ to TCHAR*

I have a class which collects all paths to .txt files of a given folder and stores them into a vector. Most of the functions I use require the usage of TCHAR* to get/set current directory and so on.
The class looks like this:
typedef std::basic_string<TCHAR> tstring;
class folderManager
{
private:
TCHAR searchTemplate[MAX_PATH];
TCHAR directory[MAX_PATH];
WIN32_FIND_DATA ffd;
HANDLE hFind;
vector<tstring> folderCatalog;
vector<tstring> fileNames;
bool succeeded;
public:
// get/set methods and so on...
};
// Changed TCHAR* dir to tstring dir
void folderManager::setDirectory(tstring dir)
{
HANDLE hFind = NULL;
succeeded = false;
folderCatalog.clear();
fileNames.clear();
// Added .c_str()
SetCurrentDirectory(dir.c_str());
GetCurrentDirectoryW(MAX_PATH, directory);
TCHAR fullName[MAX_PATH];
StringCchCat(directory, MAX_PATH, L"\\");
StringCchCopy(searchTemplate, MAX_PATH, directory);
StringCchCat(searchTemplate, MAX_PATH, L"*.txt");
hFind = FindFirstFile(searchTemplate, &ffd);
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
FindClose(hFind);
return;
}
do
{
StringCchCopy(fullName, MAX_PATH, directory);
StringCchCat(fullName, MAX_PATH, ffd.cFileName);
folderCatalog.push_back(fullName);
fileNames.push_back(ffd.cFileName);
}
while (FindNextFile(hFind, &ffd) != 0);
FindClose(hFind);
succeeded = true;
}
This is where I need to do the conversion of System::String^ to TCHAR*
private: System::Void dienuFolderisToolStripMenuItem_Click(System::Object^
sender, System::EventArgs^ e)
{
FolderBrowserDialog^ dialog;
dialog = gcnew System::Windows::Forms::FolderBrowserDialog;
System::Windows::Forms::DialogResult result = dialog->ShowDialog();
if (result == System::Windows::Forms::DialogResult::OK)
{
// Conversion is now working.
tstring path = marshal_as<tstring>(dialog->SelectedPath);
folder->setDirectory(path);
}
}
marsha_as "Performs the marshaling on a specific data object to convert it between a managed and a native data type".
Here there is the table for possible type conversion.
I use it this way:
marshal_as<std::wstring>(value)
TCHAR can be char or wchar_t, both of them present in marshal_as specialization, I suppose you need to point TCHAR* as template parameter:
TCHAR* result = marshal_as<TCHAR*>(value)
Actually MSDN says that you have to use it this way:
#include <msclr\marshal.h>
using namespace System;
using namespace msclr::interop;
int main(array<System::String ^> ^args)
{
System::String^ managedString = gcnew System::String("Hello World!!!");
marshal_context ^ context = gcnew marshal_context();
const wchar_t* nativeString = context->marshal_as<const wchar_t*>(managedString);
//use nativeString
delete context;
return 0;
}

How can i make that in the List codec's it will also show me the type of each codec?

The type of each codec or the type of the codec's
In the List i have in the end about 500 codec's i want that for example in the List in the beginning it will show for example:
Audio
mpeha
mpegv
.....
Video
xvid
divx
And so on.
The first two functions to get the List of codec's are in C:
const char* Encoder_GetNextCodecName()
{
current_codec = av_codec_next(current_codec);
while (current_codec != NULL)
{
return current_codec->name;
}
return "";
}
const char* Encoder_GetFirstCodecName()
{
current_codec = NULL;
return Encoder_GetNextCodecName();
}
Then i have header file:
const char* Encoder_GetNextCodecName();
const char* Encoder_GetFirstCodecName();
Then another C++ header file where i create the List:
List<String^> ^GetCodecs()
{
List<String^> ^l = gcnew List<String^>;
String ^s = gcnew String(Encoder_GetFirstCodecName());
while (!String::IsNullOrEmpty(s))
{
l->Add(s);
s = gcnew String(Encoder_GetNextCodecName());
}
return l;
}
Then when i'm doing in CSHARP this:
List<string> l = new List<string>(f.GetCodecs());
I see that the variable l containing 506 codec's .
The codec's are of ffmpeg !!!
Now in the C file there is also something like:
current_codec->type
Which have many properties.
And there is also something like this in the C file:
AVMediaType::
Which give me a 7 categories of types of the codec's.
The problem is how do i make in the C++ header file when i create the List that the List will be with the types of each codec or of each group of codec's like : Audio,Video,Data.... ?
EDIT
This is another header file i have that is connecting between the C functions and the CLI:
I have another header file where i first call the functions from C:
ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
bool Encoder_MoveToNextCodec();
bool Encoder_MoveToFirstCodec();
const char* Encoder_GetCurrentCodecName();
int Encoder_GetCurrentCodecType();
#ifdef __cplusplus
} // extern "C"
#endif
This is my CLI code:
#pragma once
// FFMPEG_WRAPPER.cpp : Defines the exported functions for the DLL application.
//
#include "ENCODER.h"
#include <stdlib.h>
#include <string.h>
#include <msclr\marshal.h>
#include <vcclr.h>
#include <cstdlib>
#include <Windows.h>
using namespace System;
using namespace System::Drawing;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;
using namespace System::Drawing::Imaging;
using namespace msclr::interop;
namespace MyVideo
{
public ref class FFMPEGWrapper
{
public:
FFMPEGWrapper(void)
{
Encoder_init();
}
ref class CodecInfo
{
public:
String^ CodecName;
int CodecType;
};
List<CodecInfo^> ^GetCodecs()
{
List<CodecInfo^> ^l = gcnew List<CodecInfo^>;
bool KeepLooping = Encoder_MoveToFirstCodec();
while (KeepLooping)
{
CodecInfo ^codec = gcnew CodecInfo();
codec->CodecName = gcnew String(Encoder_GetCurrentCodecName());
codec->CodecType = Encoder_GetCurrentCodecType();
l->Add(codec);
KeepLooping = Encoder_MoveToNextCodec();
}
return l;
}
Then in CSHARP i did:
List<f.CodecInfo> l = f.GetCodecs();
But CodecInfo is not exist and i'm getting an error on the GetCodecs()
Error 1 Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
Error 2 'ScreenVideoRecorder.Form1.f' is a 'field' but is used like a 'type'
The problems the errors are in CSHARP.
You need to expand your C code to expose the extra details you want, eg:
__declspec(thread) AVCodec* current_codec = NULL;
bool Encoder_MoveToNextCodec()
{
current_codec = av_codec_next(current_codec);
return (current_codec != NULL);
}
bool Encoder_MoveToFirstCodec()
{
current_codec = NULL;
return Encoder_MoveToNextCodec();
}
const char* Encoder_GetCurrentCodecName()
{
if (current_codec != NULL)
return current_codec->name;
return "";
}
int Encoder_GetCurrentCodecType()
{
if (current_codec != NULL)
return (int) current_codec->type;
return AVMEDIA_TYPE_UNKNOWN;
}
Then expand your CLI code to store that info:
ref class CodecInfo
{
public:
String^ CodecName;
int CodecType;
...
};
List<CodecInfo^> ^GetCodecs()
{
List<CodecInfo^> ^l = gcnew List<CodecInfo^>;
bool KeepLooping = Encoder_MoveToFirstCodec();
while (KeepLooping)
{
CodecInfo ^codec = gcnew CodecInfo();
codec->CodecName = gcnew String(Encoder_GetCurrentCodecName());
codec->CodecType = Encoder_GetCurrentCodecType();
...
l->Add(codec);
KeepLooping = Encoder_MoveToNextCodec();
}
return l;
}
Then lastly, use the new info as needed:
List<CodecInfo> l = f.GetCodecs();
foreach(CodecInfo codec in l)
{
// use codec.CodecName, codec.CodecType, ... as needed
}