I am trying to port a python PyTorch model to LibTorch in C++.
In python the line of code within a subclass of a torch.Module object
self.A = nn.Parameter(A) where A is a torch.tensor object with requires_grad=True.
What would be the equivalent of this for a torch::Tensor in a torch::nn::Module class in C++ ?
The autocomplete in my editor shows the classes ParameterDict, ParameterList,
ParameterDictImpl, ParamaterListImpl, but no Parameter. Do I need to wrap it in a list of size 1 or is there something else I'm missing. I wasn't able to find what I needed from a google search or the documentation, but I wasn't sure precisely what to search to be honest.
To register a parameter (or tensor which requires gradients) to a module, you could use:
m.register_parameter("A", torch::ones({20, 1, 5, 5}), True);
in libtorch.
Related
I am attempting to use Google's ORTools in Python to run an optimization. The catch is that the calculations I am trying to optimize have to be accessed through COM, as they are contained in a proprietary piece of external software. Is there any way to accomplish this?
The COM Object accepts integer or float values as inputs, but ORTools passes variables as variable objects, so the COM object is unable to use them. I attempted to get around this by using the solution_value() method, as this was the only method I could find to access variable values, but this issues the following error message and causes the solver to stop working:
"The model has been changed since the solution was last computed. MPSolverInterface:: sync_status_ = 0".
If I just pass the variable to the COM Object, I get the following error:
"Exception has occurred: TypeError. must be real number, not Variable."
See below for my example code:
from ortools.linear_solver import pywraplp
import win32com.client as win32
Program = win32.Dispatch("CalcProgram")
def Calculations(x,y):
Program.SetValue(x)
Program.SetValue(y.solution_value())
return Program.GetValue(Z)
solver = pywraplp.Solver.CreateSolver('SCIP')
x = solver.IntVar(1,25)
y = solver.IntVar(30,60)
solver.Minimize(Calculations(x,y))
status = solver.Solve()
You are missing the point of the linear solver and how to use it.
solver.Minimize() takes a linear expression, that is a python object built with overloaded +, -, * operators and variables and constants.
a valid call could be:
solver.Minimize(x + 2 * y)
Furthermore, solution_value() can only called after a successful Solve().
You should look at python samples to see how programs are structured.
See https://github.com/google/or-tools/blob/stable/ortools/linear_solver/samples/simple_mip_program.py
PyCharm Version: 2019.1.2
Python Version: 3.7
I am trying to use least code to reproduce the problem. And this is the snippet of my code:
def sql_reader():
def outer(func):
def wrapped_function(*args, **kwargs):
func(*args, **kwargs)
return [{"a": 1, "b": 2}]
return wrapped_function
return outer
#sql_reader()
def function_read():
return "1"
result = function_read()
for x in result:
print(x['a'])
print(result)
Basically, what I am doing is to "decorate" some function to output different types. For example, in this snippet, the function being decorated is returning 1 which is int. However, in decorator, I change the behavior and return list of dict.
Functionally speaking, it works fine. But it looks like my IDE always complains about it which is annoying as below:
Is there anyway I can get rid of this warning message?
With all due respect, you are using an over 3 year old version of PyCharm. I struggle to see a reason for this. The community edition is free and requires no root privileges to unpack and run on Linux systems. You should seriously consider upgrading to the latest version.
Same goes for Python by the way. You can install any version (including the latest) via Pyenv without root privileges. Although the Python version requirement may be subject to external restrictions for the code you are working on, so that is just a suggestion. But for the IDE I see no reason to use such an outdated version.
Since I am not using your PyCharm version, I can not reproduce your problem. Version 2022.2.3 has no such issues with your code. Be that as it may, there are a few things you can do to make life easier for static type checkers (and by extension for yourself).
The first thing I would always suggest is to use functools.wraps, when you are wrapping functions via a decorator. This preserves a lot of useful metadata about the wrapped function and even stores a reference to it in the wrapper's __wrapped__ attribute.
The second is proper type annotations. This should go for any code you write, unless it really is just a quick-and-dirty draft script that you will only use once and then throw away. The benefits of proper annotations especially in conjunction with modern IDEs are huge. There are many resources out there explaining them, so I won't go into details here.
In this concrete case, proper type hints will remove ambiguity about the return types of your functions and should work with any IDE (bugs non withstanding). In my version of PyCharm the return type of your wrapper function is inferred to be Any because no annotations are present, which prevents any warning like yours to pop up, but also doesn't allow any useful auto-suggestions to be provided.
Here is what I would do with your code: (should be compatible with Python 3.7)
from functools import wraps
from typing import Any, Callable, Dict, List
AnyFuncT = Callable[..., Any]
ResultsT = List[Dict[str, int]]
def sql_reader() -> Callable[[AnyFuncT], Callable[..., ResultsT]]:
def outer(func: AnyFuncT) -> Callable[..., ResultsT]:
#wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> ResultsT:
func(*args, **kwargs)
return [{"a": 1, "b": 2}]
return wrapper
return outer
#sql_reader()
def function_read() -> str:
return "1"
Adding reveal_type(function_read()) underneath and calling mypy on this file results in the following:
note: Revealed type is "builtins.list[builtins.dict[builtins.str, builtins.int]]"
Success: no issues found in 1 source file
As you can see, at least mypy now correctly infers the type returned by the wrapper function we put around function_read. Your IDE should also correctly infer the types involved, but as I said I cannot verify this with my version.
Moreover, now PyCharm will give you auto-suggestions for methods available on the types involved:
results = function_read()
first = results[0]
value = first["a"]
If I now start typing results., PyCharm will suggest things like append, extend etc. because it recognizes result as a list. If I type first., it will suggest keys, values etc. (inferring it as a dictionary) and if I type value. it will give options like imag, real and to_bytes, which are available for integers.
More information: typing module docs
I am using gurobipy to read LP files. The command
model=gurobipy.read("name.lp", env=env) gives me the number of rows, columns, and non-zeroes. However, I need to retrieve the number of non-zeroes. I don't believe there is a function that does this automatically (i.e. model.getnonzeros() )
Is there a way to obtain the non-zeros? How would I write python code to be able to do this if there isn't a built in function?
Consulted resources
Get constraints in matrix format from gurobipy
Ok I figured it out - perusing the Gurobi reference manual, in chapter 6, Python API overview, I see there is an attribute called "NumNZs" that can be called as:
print(model.getAttr("NumNZs"))
This will give the non-zeroes
I am exploring convolution layer in keras from:
https://github.com/fchollet/keras/blob/master/keras/layers/convolutional.py#L233
everywhere i found following type of code lines:
#interfaces.legacy_conv1d_support
#interfaces.legacy_conv2d_support
what is working and role of these lines. I searched in google but not find answer anywhere. please explain.
These lines starting with # are called decorators in python. Check out this page to read a brief summary about them. The basic function of this decorators is, that they wrap the following function into another function which has some kind of "wrapper" functions, like preprocessing the arguments, changing the accessibility of the function etc.
Taking a look at the interfaces.py file you will see this:
legacy_conv1d_support = generate_legacy_interface(
allowed_positional_args=['filters', 'kernel_size'],
conversions=[('nb_filter', 'filters'),
('filter_length', 'kernel_size'),
('subsample_length', 'strides'),
('border_mode', 'padding'),
('init', 'kernel_initializer'),
('W_regularizer', 'kernel_regularizer'),
('b_regularizer', 'bias_regularizer'),
('W_constraint', 'kernel_constraint'),
('b_constraint', 'bias_constraint'),
('bias', 'use_bias')],
preprocessor=conv1d_args_preprocessor)
So, the use of this function is basicly to rename parameters. Why is this? The keras API changed the names of some arguments of some functions (like W_regularizer -> kernel_regularizer). To allow users to be able to run old code, they added this decorator, which will just replace the names of old arguments with the corresponding new parameter name before calling the real function. This allows you to run "old" keras 1 code, even though you have installed keras 2.
Tl;dr: These lines are just used to for compatibility reasons. As this are just internal aspects of keras there is nothing you have to worry about or to take care of.
I'm trying to use ctypes to use fann (a neural network library written in C) in python3. Here is my abridged code so far:
from ctypes import *
cdll.LoadLibrary("/usr/local/lib/libdoublefann.dylib")
fann = CDLL("/usr/local/lib/libdoublefann.dylib")
# Call fann to create a neural network
nn = fann.fann_create_from_file(b'/Users/xxxxx/Code/fanncode/net/nnf_25_1339802027.net')
# this outputs 3909360
print(nn)
If I try and call any other functions in the fann library against the nn variable, which should now be a fann neural network, I either get Segmentation fault: 11 or AttributeError: 'int' object has no attribute 'getMSE' (for example). I think my problem is that according to the ctypes documentation, the variable nn is ending up being an int, whereas the fann documentation for the function fann_create_from_file states:
FANN_EXTERNAL struct fann *FANN_API fann_create_from_file(const char * configuration_file)
So I think I need to declare:
class FANN_API(Structure):
<fields and things which I don't know what they should be>
And then do:
fann.fann_create_from_file.restype = FANN_API
My problem is that I can't find what the struct FANN_API should be. Line 130 of fann.h states #define FANN_API but thats it, no definition or anything follows it.
Am I correct in my guess about needing to define the struct? If so, then how can I find out the format of it to declare in the python code? If not then can anybody suggest what I might need to do/what to read to get my code to work?
Thanks!
You can tell ctypes the arguments and return codes of functions. You should be able to get away with c_void_p (void*) as the type unless you have some reason to manipulate the contents of the structure:
fann.fann_create_from_file.restype = c_void_p
fann.fann_create_from_file.argtypes = [c_char_p]
Note that struct fann * is the return type of your function. FANN_API represents the calling convention. You've said it is defined as #define FANN_API. Being defined as nothing means the default calling convention, so your use of CDLL should be correct.
If you need to define something more specific, post the definition of struct fann.