where can I find the source code for torch.unique()? - pytorch

I can only find in the pytorch source code (https://github.com/pytorch/pytorch/blob/2367face24afb159f73ebf40dc6f23e46132b770/torch/functional.py#L783) the following function call:
_VF.unique_dim() and torch._unique2()
but they don't point to anywhere else in the directory

Most of the pytorch backend code is implemented in C++ and/or CUDA. To see it you need to find the appropriate entrypoint in the source code. There are a couple ways to do this but the easiest I've found without downloading all the code yourself is to search for the keywords on github.
For example, if you go to github.com and the search for unique_dim repo:pytorch/pytorch, then click the "Code" tab on the left side you should quickly find the following.
From torch/jit/_builtins.py:103
17: _builtin_ops = [
...
103: (torch._VF.unique_dim, "aten::unique_dim"),
From this and further analysis of the code we can conclude that torch._VF.unique_dim is actually invoking the aten::unique_dim function from the ATen library.
Like most functions in ATen there are multiple implementations of this function. Most ATen functions are registered in aten/src/ATen/native/native_functions.yaml, generally the functions here will have a _cpu and _cuda version.
Going back to the search results we can find that the CUDA implementation is actually calling the function unique_dim_cuda at aten/src/ATen/native/cuda/Unique.cu:197
196: std::tuple<Tensor, Tensor, Tensor>
197: unique_dim_cuda(const Tensor& self, const int64_t dim, const bool sorted, const bool return_inverse, const bool return_counts) {
198: return AT_DISPATCH_ALL_TYPES_AND2(kBool, kHalf, self.scalar_type(), "unique_dim", [&] {
199: return unique_dim_cuda_template<scalar_t>(self, dim, false, return_inverse, return_counts);
200: });
201: }
and the CPU implementation is calling the function unique_dim_cpu at aten/src/ATen/native/Unique.cpp:271
270: std::tuple<Tensor, Tensor, Tensor>
271: unique_dim_cpu(const Tensor& self, const int64_t dim, const bool sorted, const bool return_inverse, const bool return_counts) {
272: return AT_DISPATCH_ALL_TYPES_AND2(at::ScalarType::BFloat16, at::ScalarType::Bool, self.scalar_type(), "unique_dim", [&] {
273: // The current implementation using `dim` always sorts due to unhashable tensors
274: return _unique_dim_cpu_template<scalar_t>(self, dim, false, return_inverse, return_counts);
275: });
276: }
From this point you should be able to trace the function calls further down to see exactly what they are doing.
Following a similar string of searches you should find that torch._unique2 is implemented at aten/src/ATen/native/cuda/Unique.cu:188 and aten/src/ATen/native/Unique.cpp:264 for CUDA and CPU respectively.

Related

Using nannou.rs, how can I provide the correct parameters to the load_from_image_buffer method?

I am currently trying to learn Nannou.rs. I generate a Luma8 image (corresponding to a Perlin heightmap) and I am trying to display it in my app's window using the function load_from_image_buffer implemented by nannou::wgpu::Texture in the model function as follow:
fn model(app: &App) -> Model {
let img_buf = NoiseBuilder::generate_image(256, 8, 8, None);
let texture = wgpu::Texture::load_from_image_buffer(device, queue, usage, &img_buf).unwrap();
Model { texture }
}
As you can see, in this snippet I am not defining the device, queue and usage parameters. I tried multiple things but nothing worked, and online resources are rather scarce.
So my question really is how can I provide this parameters?
I played around first with the from_image function and it worked, but as I am trying to learn my way around the library I am interested in the use of this specific function. Also this parameters are required by many other methods and I ll need to understand it anyway.
The wgpu module imported in the snippet above is the nannou::wgpu and not directly the wgpu crate.
The NoiseBuilder::generate_image return an ImageBuffer<Luma<u8>, Vec<u8>> variable.
You can use the trait method with_device_queue_pair which is defined in the trait WithDeviceQueuePair and implemented for either App or Window.
The usage is just the normal wgpu::TextureUsages.
So if you would like to mimic the from_path function of the texture you could do something like this (untested):
fn model(app: &App) -> Model {
let img_buf = NoiseBuilder::generate_image(256, 8, 8, None);
let usage = nannou::wgpu::TextureUsages::COPY_SRC |
nannou::wgpu::TextureUsages::COPY_DST |
nannou::wgpu::TextureUsages::RENDER_ATTACHMENT;
src.with_device_queue_pair(|device, queue| {
let texture = wgpu::Texture::load_from_image_buffer(device, queue, usage, &img_buf).unwrap();
Model { texture }
})
}

Where is torch.cholesky and how torch refers to its methods?

I'm doing some research into Cholesky decomposition, which requires some insights into how torch.cholesky works. After a while of grep-ing and searching through ATen, I got stuck at TensorMethods.h, which interestingly has this following code:
inline Tensor Tensor::cholesky(bool upper) const {
#ifdef USE_STATIC_DISPATCH
return TypeDefault::cholesky(const_cast<Tensor&>(*this), upper);
#else
static c10::OperatorHandle op = c10::Dispatcher::singleton().findSchema({"aten::cholesky", ""}).value();
return c10::Dispatcher::singleton().callUnboxed<Tensor, const Tensor &, bool>(
op, impl::dispatchTypeId(at::detail::multi_dispatch_tensor_type_set(*this)), const_cast<Tensor&>(*this), upper);
#endif
}
This raised the question of how torch locates its methods. Thank you!
Take a look at aten/src/ATen/native/README.md which describes how functions are registered to the API.
ATen "native" functions are the modern mechanism for adding operators
and functions to ATen (they are "native" in contrast to legacy
functions, which are bound via TH/THC cwrap metadata). Native
functions are declared in native_functions.yaml and have
implementations defined in one of the cpp files in this directory.
If we take a look at aten/src/ATen/native/native_functions.yaml and search for cholesky we find
- func: cholesky(Tensor self, bool upper=False) -> Tensor
use_c10_dispatcher: full
variants: method, function
To find the entry-point you basically just have to search the .cpp files in the aten/src/ATen/native directory and locate the function named cholesky. Currently it can be found at BatchLinearAlgebra.cpp:550
Tensor cholesky(const Tensor &self, bool upper) {
if (self.size(-1) == 0) {
return at::empty_like(self, LEGACY_CONTIGUOUS_MEMORY_FORMAT);
}
squareCheckInputs(self);
auto raw_cholesky_output = at::_cholesky_helper(self, upper);
if (upper) {
return raw_cholesky_output.triu_();
} else {
return raw_cholesky_output.tril_();
}
}
From this point it's just a matter of following the C++ code to understand what's going on.

ANTLR4: getFirstChildWithType with a ParseTree

I've been playing around with ANTLR4, trying to convert an ANTLR3 project.
I have generated a lexer, a parser and a visitor class from an ANLTR4 grammar coming from the official repository. In the visitor, I am calling one of my classes using the ctx available from the visitor:
myFunction(ctx.getChild(0))
Then, in myFunction, I want to retrieve the first child having a specific type, so I tried doing:
final ParseTree classNameElement =
(ParseTree) ((GrammarAST) node).getFirstChildWithType(MyParser.IDENTIFIER);
where node is the argument of myFunction, thus a ParseTree. getFirstChildWithType seems to be available only in GrammarAST, hence the cast.
I am getting the error: cannot be cast to org.antlr.v4.tool.ast.GrammarAST
So maybe this is not possible as is and I must have missed something, but I want to find the first child having a specific type from a ParseTree.
Thank you!
Notice that GrammarAST is in the ANTLR tool hierarchy. With a generated parse-tree, you should be dealing exclusively with the runtime.
To search a parse-tree node for a child of a given type:
public ParseTree getFirstChildOfType(ParseTree node, int tokentype) {
for (int idx = 0; idx < node.getChildCount(); idx++) {
ParseTree child = node.getChild(idx);
if (child instanceof TerminalNode) {
Token token = (Token) child.getPayload();
if (token.getType() == tokentype) {
return child;
}
}
}
return null;
}
This will get the first direct, i.e., child terminal, of the given type. Will need to recurse into non-TerminalNodes if the absolute first of type is desired.
If the latter is actually the desired function, there may be a better/more direct use of parse-tree walker to obtain the desired overall goal.

OpenCV, How to pass parameters into cv2.TrackerMedianFlow_create function?

I'm trying to create MEDIANFLOW tracker with OpenCV3.3 using opencv-python with Python3.6. I need to pass some arguments into the constructor according to this page of OpenCV docs.
The problem is I don't know how to pass available arguments into this function correctly? I wasn't able to find any information about it.
What I do (and it works):
tracker = cv2.TrackerMedianFlow_create()
What I want to do:
tracker = cv2.TrackerMedianFlow_create(maxLevel=3)
But it doesn't work and gives me an error:
SystemError: <built-in function TrackerMedianFlow_create> returned NULL without setting an error
Could you help?
I search the intermediate code generated by cmake/make when compiling the OpenCV 3.3 for Python 3.5, just cannot find the methods to set the parameters for cv2.TrackerXXX.
In modules/python3/pyopencv_generated_funcs.h, I find this function:
static PyObject* pyopencv_cv_TrackerMedianFlow_create(PyObject* , PyObject* args, PyObject* kw)
{
using namespace cv;
Ptr<TrackerMedianFlow> retval;
if(PyObject_Size(args) == 0 && (kw == NULL || PyObject_Size(kw) == 0))
{
ERRWRAP2(retval = cv::TrackerMedianFlow::create());
return pyopencv_from(retval);
}
return NULL;
}
This is to say, you cann't pass any parameter to cv::TrackerMedianFlow_create().
In modules/python3/pyopencv_generated_types.h, I find this one:
static PyGetSetDef pyopencv_TrackerMedianFlow_getseters[] =
{
{NULL} /* Sentinel */
};
This to say, you have no way to change the parameters for Python wrapper by default, Unless you modified the source code and recompile it.
You can customize Tracker parameters via FileStorage interface.
import cv2
# write
tracker = cv2.TrackerMedianFlow_create()
tracker.save('params.json')
# write (another way)
fs = cv2.FileStorage("params.json", cv2.FileStorage_WRITE)
tracker.write(fs)
fs.release()
# read
tracker2 = cv2.TrackerMedianFlow_create()
fs = cv2.FileStorage("params.json", cv2.FileStorage_READ)
tracker2.read(fs.getFirstTopLevelNode())

WinRT Asynchronous File operations in C++

I'm currently working on a metro app that requires a few textual resources. Part of the build process is copying all of these resources to a folder inside of the app's installation directory. What I'd like to do is gather a list of these resource files, and process each one accordingly. Unfortunately, my attempts to do so have been less than successful.
Since I'm building for WinRT, I can't use the very useful "FindFirstFile" and "FindNextFile" functions. I've been trying to get the job done using the WinRT Asynchronous file IO operations.
auto getResourceFolder = installedLocation->GetFolderFromPathAsync( folderPath );
getResourceFolder->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< Windows::Storage::StorageFolder^ >(
[this]( Windows::Foundation::IAsyncOperation< Windows::Storage::StorageFolder^ >^ operation ) {
if( operation->Status == Windows::Foundation::AsyncStatus::Completed ) {
auto resourceFolder = operation->GetResults();
auto getResourceFiles = resourceFolder->GetFilesAsync();
getResourceFiles->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< IVectorView< Windows::Storage::IStorageFile^ >^ >(
[this]( Windows::Foundation::IAsyncOperation< IVectorView< Windows::Storage::IStorageFile^ >^ >^ operation ) {
if( operation->Status == Windows::Foundation::AsyncStatus::Completed ) {
auto resourceFiles = operation->GetResults();
for( unsigned int i = 0; i < resourceFiles->Size; ++i ) {
// Process File
}
}
});
}
});
Which fails to compile:
error C2664: 'Windows::Foundation::IAsyncOperation<TResult>::Completed::set' : cannot convert parameter 1 from 'Windows::Foundation::AsyncOperationCompletedHandler<TResult> ^' to 'Windows::Foundation::AsyncOperationCompletedHandler<TResult> ^'
The error isn't making any sense to me. I've tried rewriting the above code so that the lambda handler functions are not inline, but it hasn't made a difference. I'm not sure what's wrong.
Any ideas? Thanks in advance.
[Note: I have omitted most namespace qualification from the code and error messages for brevity.]
The Visual Studio Error List pane only shows the first line of each error (this is a very useful feature, especially when programming in C++, because some error messages from the compiler are exceedingly long. You need to look at the Output window to see the rest of the error message:
error C2664: 'IAsyncOperation<TResult>::Completed::set' :
cannot convert parameter 1
from 'AsyncOperationCompletedHandler<TResult> ^'
to 'AsyncOperationCompletedHandler<TResult> ^'
with
[
TResult=IVectorView<StorageFile ^> ^
]
and
[
TResult=IVectorView<IStorageFile ^> ^
]
and
[
TResult=IVectorView<StorageFile ^> ^
]
No user-defined-conversion operator available, or
Types pointed to are unrelated;
conversion requires reinterpret_cast, C-style cast or function-style cast
This is still a bit confusing because all three templates use a parameter named TResult. To decipher the error, note that the order of the templates in the first line matches the order of the template argument lists in the rest of the line.
The issue here is that you are mixing usage of StorageFile and IStorageFile. On both of these lines, you need to use StorageFile (see carrots under lines for where IStorageFile is used):
getResourceFiles->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler< IVectorView< Windows::Storage::IStorageFile^ >^ >(
^
[this]( Windows::Foundation::IAsyncOperation< IVectorView< Windows::Storage::IStorageFile^ >^ >^ operation ) {
^
Note that once you fix this issue, you'll get another pair of errors because your lambdas need to have two parameters; the second is an AsyncStatus. In the end, they should both be declared as:
// Namespaces omitted for brevity
[this](IAsyncOperation<StorageFolder^>^ operation, AsyncStatus status) { }
Since I'm building for WinRT, I can't use the very useful FindFirstFile and FindNextFile functions.
Note that you can, in fact, use both FindFirstFileEx and FindNextFile in a Metro style app. (The non-Ex FindFirstFile is not usable).
You should use the asynchronous WinRT functions wherever you can and wherever it is practical, but that doesn't mean there isn't still a use for these other functions.
A far simpler solution is to use PPL for your async operations. Instead of manually rolling the async operation, try:
create_task(installedLocation->GetFolderFromPathAsync(folderPath)
.then([this](Windows::Storage::StorageFolder^ folder) {
return folder->GetFilesAsync();
})
.then([this](IVectorView<Windows::Storage::StorageFile^ >^ files) {
for( unsigned int i = 0; i < files->Size; ++i ) {
// Process File
}
});
I'm not 100% on the syntax, this was written in the SO code editor, but it shows how PPL dramatically reduces the complexity of this kind of code - basically you use create_task to create a task, then use the .then method on the task to specify a lambda which is used for async completion.
EDIT: Updated to remove the nested lambda.

Resources