Low Level Functions (Expert level)
Disclaimer: don't use the scheme described here, unless you are convinced that the common array functions don't give the same result easier, faster and safer! You can work with array elements using pointers without having to deal with memory as described here!
In such rare situations, where ILNumerics arrays lack a certain feature or if you for some reasons feel to work with a raw memory region in a c-stylish way again, here is how you do in ILNumerics.
ILNumerics provides the same options for low -level memory management as the C++ language: New() and free(). Here is a quick example:
The ILMath.New<T>() function for value types T acquires a memory handle pointing to unmanaged memory. Hence, the best way to directly interact with the handles memory is via pointers or the System.RuntimeInterop.Marshal class. During the acquisition of the handle the type of elements T and the number of elements is to be provided. Currently, the memory will be fetched from an ILNumerics memory pool or be allocated from the systems virtual memory manager only.
The handle gives access to the Pointer to the first element of the memory region. Note, no pinning is required since the memory lives on the unmanaged heap.
As long as the handle is alive no other threads will access its memory. Whether a handle is alive or not can be determined by querying the value of its IsClosed property.
Once the handle is not used anymore it should be freed. Note, that to free a handle manually is recommended but not absolutely necessary: ILNumerics handles are implemented in a safe way which guarantees that the memory referenced by the handle is freed by the finalizer - even after a critical failure.
However, deallocation is recommended to give up ownership of the handle and to allow ILNumerics memory management to reuse the memory rather sooner than later.
In order to release a handle, it is given to the ILMath.free() method. By default, the handle is not deallocated with the systems virtual memory manager but stored into an ILNumerics pool for later retrieval and reusing.
After releasing a handle it cannot be used anymore. Likewise, the memory referenced by the handle cannot be used anymore! Thus, the pointer acquired from MemoryHandle.Pointer is invalidated.
Note, that the free() method expects two additional information: the element type used at the time the handle was created and a device ID. Devices will play a bigger role in ILNumerics version 6. For now, just provide 0 as device ID.
Note further, that you can access the memory regions used to store the elements of ILNumerics array, too. This is covered in the section I/O and ILNumerics arrays.
Please, make sure to read the following ...
IMportant Note for release builds
When the JIT finds a Release build in Release mode it is very eagerly trying to mark objects as ready for garbage collection as early as possible. This can cause the memory handle to be released before the functions scope ends. In case that we have a pointer to the memory for the handle around, this pointer may gets invalidated too early! In order to prevent from AccessViolationExceptions caused by such issues make sure to keep the handle alive until the end of the function. This can be achieved (for example) by placing a call to GC.KeepAlive(handle) near the end of the scope.
See also: I/O and ILNumerics arrays