Disallow copy with functions taking PyBind11 arrays - numpy

I have created a function which takes a py::array_t<double> as input.
When calling it from Python, I can pass as input a NumPy array with either float32 or float64 dtype. My issue with this is that if the former dtype is used, it will inevitably incur a "silent" copy of the array in order to coerce it to float64.
I would like to disable all such silent copies (e.g., produce an error if a float32 array is passed).
For the same reason, I would also like to disallow inputs that are not C-contiguous since my function assumes C-contiguity.
Are any of these things possible to do (easily) with PyBind11?

The best that I have found is taking as an argument not
py::array_t<double> &my_object
but instead
py::buffer & my_object
which is more general
Then
py::buffer_info buffer_info = my_object.request();
if( buffer_info.format[0] != 'd') {
throw std::invalid_argument("The argument must be an array of float64");
}
the buffer structure contains ndim, shape, strides, itemsize and more. With that you can check if the array is contiguous, c_style, f_style. The data itself is member void *ptr.
To check contiguity
bool check_c_contiguity(py::buffer_info &info) {
int ndim = info.ndim;
size_t stride = 0;
size_t prod=1;
for(int i=ndim-1; i>=0; i--) {
stride = prod * info.itemsize ;
prod = prod * info.shape[i];
if ( stride != info.strides[i] ) {
return false;
}
}
return true;
}
bool check_f_contiguity(py::buffer_info &info) {
int ndim = info.ndim;
size_t stride = 0;
size_t prod=1;
for(int i=0; i<ndim; i++) {
stride = prod * info.itemsize;
prod = prod * info.shape[i];
if ( stride != info.strides[i] ) {
return false;
}
}
return true;
}

Related

Pset5 (Speller) Weird Valgrind memory errors, no leaks

I have read other threads on pset5 Valgrind memory errors, but that didn't help me. I get 0 leaks, but this instead:
==1917== Conditional jump or move depends on uninitialised value(s)
Looks like you're trying to use a variable that might not have a value? Take a closer look at line 34 of dictionary.c.
The error refers to line 34 which is this: lower[i] = tolower(word[i]);
To supply context, the code below attempts to check if a word exists in the dictionary that has been uploaded to a hash table. I am attempting to convert the wanted word to lowercase because all the dictionary words are also lowercase and so that their hashes would be identical. The program successfully completes all tasks, but then stumbles upon these memory errors.
Any hints as to why Valgrind is mad at me? Thank you!
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
Below is the whole dictionary.c file:
// Implements a dictionary's functionality
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table 26^3
const unsigned int N = 17576;
// Hash table
node *table[N];
int count = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// Modified hash function by Dan Berstein taken from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash = 5381;
int c;
while ((c = *word++))
{
hash = (((hash << 5) + hash) + c) % N; /* hash * 33 + c */
}
return hash;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *inptr = fopen(dictionary, "r");
if (dictionary == NULL)
{
printf("Could not load %s\n.", dictionary);
return false;
}
// Create a char array to temporarily hold the new word (r stands for read)
char r_word[N+1];
// Until the end of file
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
// Hash the node
int index = hash(new_node->word);
// Places the node at the right index
new_node->next = table[index];
table[index] = new_node;
}
fclose(inptr);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (&load == false)
{
return '0';
}
else
{
return count;
}
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// Interates over the array
for (int i = 0; i < N; i++)
{
node *head = table[i];
while (head != NULL)
{
node *tmp = head;
head = head->next;
free(tmp);
}
}
return true;
}
This loop iterates through the maximum length of word-
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
Except if you look at how word is created-
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
Notice, the variable r_word, may not be exactly of length LENGTH + 1. So what you really have in word is N number of characters, where N is not necessarily LENGTH + 1, it could be less.
So looping over the entire 0 -> LENGTH + 1 becomes problematic for words that are shorter than LENGTH + 1. You're going over array slots that do not have a value, they have garbage values.
What's the solution? This is precisely why c strings have \0-
for (int i = 0; word[i] != '\0'; i++)
{
lower[i] = tolower(word[i]);
}
This will stop the loop as soon as the NULL character is reached, which, you must have already learnt, marks the end of a string - aka a char array.
There may still be more errors in your code. But for your particular question - reading out of bounds is the answer.

What is a need of defining indegree vector in private for finding All Topological Sorts of DAG?

What is the importance of defining indegree vector in the private of a class? It could have been defined in alltopologicalSort() function.
class Graph
{
int V; // No. of vertices
// Pointer to an array containing adjacency list
list<int> *adj;
// Vector to store indegree of vertices
vector<int> indegree;
// A function used by alltopologicalSort
void alltopologicalSortUtil(vector<int>& res,
bool visited[]);
public:
Graph(int V); // Constructor
// function to add an edge to graph
void addEdge(int v, int w);
// Prints all Topological Sorts
void alltopologicalSort();
};
And how it is functioning in below addedge function
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v's list.
// increasing inner degree of w by 1
indegree[w]++;
}
Use of indegree, please explain here the role of addEdge function in decrementing indegree
void Graph::alltopologicalSortUtil(vector<int>& res,
bool visited[])
{
// To indicate whether all topological are found
// or not
bool flag = false;
for (int i = 0; i < V; i++)
{
// If indegree is 0 and not yet visited then
// only choose that vertex
if (indegree[i] == 0 && !visited[i])
{
// reducing indegree of adjacent vertices
list<int>:: iterator j;
for (j = adj[i].begin(); j != adj[i].end(); j++)
indegree[*j]--;
// including in result
res.push_back(i);
visited[i] = true;
alltopologicalSortUtil(res, visited);
// resetting visited, res and indegree for
// backtracking
visited[i] = false;
res.erase(res.end() - 1);
for (j = adj[i].begin(); j != adj[i].end(); j++)
indegree[*j]++;
flag = true;
}
}
}
This is the link to complete code of finding All Topological Sorts of Directed Acyclic Graph
https://www.geeksforgeeks.org/all-topological-sorts-of-a-directed-acyclic-graph/
I have got my answer from above discussion with Gupta and kaya3
Indegree could have been defined in some function and then passed to alltopologicalSort() function as a reference. But then defining it in class makes it easier to deal with.
And Data members of a class are always kept private because of encapsulation rules

Implementing qsort in Objective-C

I'm trying to use qsort to sort a C array in descending order based on what this website is suggesting.
Here is the relevant code:
int x = 3;
- (IBAction)CaptureButton:(id)sender
{
x++;
if (x % 3 == 1)
{
int areas[detectedBlobs.size()];
for (int i = 0; i < detectedBlobs.size(); i++)
{
areas[i] = detectedBlobs[i].getWidth() * detectedBlobs[i].getHeight();
}
int compareInts(void const *item1, void const *item2)
{ // first error
int const *int1 = item1;
int const *int2 = item2;
return (*int2 - *int1);
}
qsort(areas, detectedBlobs.size(), sizeof(int), compareInts); // second error
}
}
Here are the two errors I'm getting:
First error:
Function definition is not allowed here
Second error:
Use of undeclared identifier 'compareInts'
If I cannot define the comparator (compareInts) function here, where do I have to define it? Also, how can I get the qsort function to recognize the comparator?
Objective-C does not allow function definitions inside methods. Move compareInts outside of the method, and make it static to hide from other translation units:
static int compareInts(const void* item1, const void* item2) {
const int* int1 = (const int*)item1;
const int* int2 = (const int*)item2;
return (*int2 - *int1);
}
- (IBAction)CaptureButton:(id)sender {
x++;
if (x % 3 == 1) {
int areas[detectedBlobs.size()];
for (int i = 0; i < detectedBlobs.size(); i++) {
areas[i] = detectedBlobs[i].getWidth() * detectedBlobs[i].getHeight();
}
qsort(areas, detectedBlobs.size(), sizeof(int), compareInts);
}
}

Is there a way to generate 2D stretched mesh using CGAL?

I currently use CGAL to generate 2D Delaunay triangulation.One of the mesh control parameter is the maximum length of the triangle edge. The examples suggests that this parameter is a constant. I would like to know how this parameter be made function of some thing else, for example spatial location.
I think Delaunay meshing with variable density is not directly supported by CGAL although you could mesh your regions independently. Alternatively you may have a look at: http://www.geom.at/advanced-mesh-generation/ where I have implemented that as a callback function.
It doesn't look like CGAL provides an example of this but they machinery is all there. The details get a little complicated since the objects that control if triangles need to be refined also have to understand the priority under which triangles get refined.
To do this, I copied Delaunay_mesh_size_criteria_2 to create a new class (Delaunay_mesh_user_criteria_2) that has a spatially varying sizing field. Buried in the class is a function (user_sizing_field) that can be implemented with a varying size field based on location. The code below compares the size of the longest edge of the triangle to the minimum of the sizing field at the three vertices, but you could use a size at the barycenter or circumcenter or even send the entire triangle to the sizing function if you have a good way to compute the smallest allowable size on the triangle altogether.
This is a starting point, although a better solution would,
refactor some things to avoid so much duplication with with existing Delaunay_mesh_size_criteria,
allow the user to pass in the sizing function as an argument to the criteria object, and
be shipped with CGAL.
template <class CDT>
class Delaunay_mesh_user_criteria_2 :
public virtual Delaunay_mesh_criteria_2<CDT>
{
protected:
typedef typename CDT::Geom_traits Geom_traits;
double sizebound;
public:
typedef Delaunay_mesh_criteria_2<CDT> Base;
Delaunay_mesh_user_criteria_2(const double aspect_bound = 0.125,
const Geom_traits& traits = Geom_traits())
: Base(aspect_bound, traits){}
// first: squared_minimum_sine
// second: size
struct Quality : public std::pair<double, double>
{
typedef std::pair<double, double> Base;
Quality() : Base() {};
Quality(double _sine, double _size) : Base(_sine, _size) {}
const double& size() const { return second; }
const double& sine() const { return first; }
// q1<q2 means q1 is prioritised over q2
// ( q1 == *this, q2 == q )
bool operator<(const Quality& q) const
{
if( size() > 1 )
if( q.size() > 1 )
return ( size() > q.size() );
else
return true; // *this is big but not q
else
if( q.size() > 1 )
return false; // q is big but not *this
return( sine() < q.sine() );
}
std::ostream& operator<<(std::ostream& out) const
{
return out << "(size=" << size()
<< ", sine=" << sine() << ")";
}
};
class Is_bad: public Base::Is_bad
{
public:
typedef typename Base::Is_bad::Point_2 Point_2;
Is_bad(const double aspect_bound,
const Geom_traits& traits)
: Base::Is_bad(aspect_bound, traits) {}
Mesh_2::Face_badness operator()(const Quality q) const
{
if( q.size() > 1 )
return Mesh_2::IMPERATIVELY_BAD;
if( q.sine() < this->B )
return Mesh_2::BAD;
else
return Mesh_2::NOT_BAD;
}
double user_sizing_function(const Point_2 p) const
{
// IMPLEMENT YOUR CUSTOM SIZING FUNCTION HERE.
// BUT MAKE SURE THIS RETURNS SOMETHING LARGER
// THAN ZERO TO ALLOW THE ALGORITHM TO TERMINATE
return std::abs(p.x()) + .025;
}
Mesh_2::Face_badness operator()(const typename CDT::Face_handle& fh,
Quality& q) const
{
typedef typename CDT::Geom_traits Geom_traits;
typedef typename Geom_traits::Compute_area_2 Compute_area_2;
typedef typename Geom_traits::Compute_squared_distance_2 Compute_squared_distance_2;
Geom_traits traits; /** #warning traits with data!! */
Compute_squared_distance_2 squared_distance =
traits.compute_squared_distance_2_object();
const Point_2& pa = fh->vertex(0)->point();
const Point_2& pb = fh->vertex(1)->point();
const Point_2& pc = fh->vertex(2)->point();
double size_bound = std::min(std::min(user_sizing_function(pa),
user_sizing_function(pb)),
user_sizing_function(pc));
double
a = CGAL::to_double(squared_distance(pb, pc)),
b = CGAL::to_double(squared_distance(pc, pa)),
c = CGAL::to_double(squared_distance(pa, pb));
double max_sq_length; // squared max edge length
double second_max_sq_length;
if(a<b)
{
if(b<c) {
max_sq_length = c;
second_max_sq_length = b;
}
else { // c<=b
max_sq_length = b;
second_max_sq_length = ( a < c ? c : a );
}
}
else // b<=a
{
if(a<c) {
max_sq_length = c;
second_max_sq_length = a;
}
else { // c<=a
max_sq_length = a;
second_max_sq_length = ( b < c ? c : b );
}
}
q.second = 0;
q.second = max_sq_length / (size_bound*size_bound);
// normalized by size bound to deal
// with size field
if( q.size() > 1 )
{
q.first = 1; // (do not compute sine)
return Mesh_2::IMPERATIVELY_BAD;
}
Compute_area_2 area_2 = traits.compute_area_2_object();
double area = 2*CGAL::to_double(area_2(pa, pb, pc));
q.first = (area * area) / (max_sq_length * second_max_sq_length); // (sine)
if( q.sine() < this->B )
return Mesh_2::BAD;
else
return Mesh_2::NOT_BAD;
}
};
Is_bad is_bad_object() const
{ return Is_bad(this->bound(), this->traits /* from the bad class */); }
};
I am also interested for variable mesh criteria on the domaine with CGAL. I have found an alternative many years ago : https://www.cs.cmu.edu/~quake/triangle.html
But i am still interested to do the same things with CGAL ... I don't know if it is possible ...

Convert short array to byte array and vice-versa and int to byte array and vice-versa in Objective-c

I am confused to convert byte array to short vice-versa and also int to byte array vice-versa in Objective-C.
I have seen in Java like following
public static short byteArrayToShort(byte[] b) {
if (b.length > 1) {
return (ByteBuffer.wrap(b)).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get();
} else {
return b[0];
}
}
/**
* Short to byte array.
*
* #param value the value
* #return the byte[]
*/
public static byte[] shortToByteArray(short value) {
return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
}
/**
* Int to byte array.
*
* #param value the value
* #return the byte[]
*/
public static byte[] intToByteArray(int value) {
return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(value).array();
}
/**
* Convert the byte array to an short starting from the given offset.
*
* #param b The byte array
* #return The integer
*/
public static int byteArrayToInt(byte[] b) {
if (b.length > 1) {
return (ByteBuffer.wrap(b)).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get();
} else {
return b[0];
}
}
In Objective-C I have tried like following:
//Byte to Short array
- (uint16_t*) byte2short:(uint8_t *)bytes size:(int)size{
uint16_t*shorts = (uint16_t*)malloc(size/2);
for (int i=0; i < size/2; i++){
shorts[i] = (bytes[i*2+1] << 8) | bytes[i*2];
}
return shorts;
}
//Short to Byte array
- (uint8_t *) short2byte:(uint16_t*)shorts size:(int)size{
uint8_t *bytes = (uint8_t *)malloc(size*2);
for (int i = 0; i < size; i++)
{
bytes[i * 2] = (uint16_t) (shorts[i] & 0x00FF);
bytes[(i * 2) + 1] = (uint16_t) (shorts[i] >> 8);
shorts[i] = 0;
}
return bytes;
}
I have tried like this and also I dont have idea in conversion of int to Byte array in Objective-c.
Please suggest me
The problem with your code is that you are assuming that malloc somehow "knows" about the size of whatever is being allocated, in the same way that Java's array new knows the difference between allocating 5 ints and 5 shorts. Well, malloc does not. Unless you tell it otherwise, it allocates the required number of bytes. That's why when you do this
uint16_t*shorts = (uint16_t*)malloc(size/2);
and then write size/2 uint16_t into it, you overrun the buffer.
A proper way of allocating an array of primitives in C (and in Objective-C, which is a superset of C) is as follows:
size_t count = (size+1)/2; // Do not assume that size is even
uint16_t *shorts = malloc(sizeof(uint16_t)*count);
Now you have enough memory to fit all your shorts.
In your other function you should use
uint8_t *bytes = malloc(sizeof(uint8_t)*size*2);
Note that the cast is unnecessary in both cases. The type of bytes variable matters, though, because that's what determines the actual address written to in bytes[i * 2] and bytes[(i * 2)+1] expressions:
for (int i = 0; i < size; i++)
{
bytes[i * 2] = (uint8_t) (shorts[i] & 0xFF);
bytes[(i * 2) + 1] = (uint8_t) (shorts[i] >> 8);
shorts[i] = 0;
}