2020-09-25 07:32:02 -04:00
|
|
|
#ifndef RUBY_MEMORY_VIEW_H
|
|
|
|
#define RUBY_MEMORY_VIEW_H 1
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @author Ruby developers <ruby-core@ruby-lang.org>
|
|
|
|
* @copyright This file is a part of the programming language Ruby.
|
|
|
|
* Permission is hereby granted, to either redistribute and/or
|
|
|
|
* modify this file, provided that the conditions mentioned in the
|
|
|
|
* file COPYING are met. Consult the file for details.
|
|
|
|
* @brief Memory View.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ruby/internal/dllexport.h"
|
|
|
|
#include "ruby/internal/stdbool.h"
|
|
|
|
#include "ruby/internal/value.h"
|
|
|
|
#include "ruby/intern.h"
|
|
|
|
|
|
|
|
enum ruby_memory_view_flags {
|
|
|
|
RUBY_MEMORY_VIEW_SIMPLE = 0,
|
|
|
|
RUBY_MEMORY_VIEW_WRITABLE = (1<<0),
|
|
|
|
RUBY_MEMORY_VIEW_FORMAT = (1<<1),
|
|
|
|
RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL = (1<<2),
|
|
|
|
RUBY_MEMORY_VIEW_STRIDES = (1<<3) | RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL,
|
|
|
|
RUBY_MEMORY_VIEW_ROW_MAJOR = (1<<4) | RUBY_MEMORY_VIEW_STRIDES,
|
|
|
|
RUBY_MEMORY_VIEW_COLUMN_MAJOR = (1<<5) | RUBY_MEMORY_VIEW_STRIDES,
|
|
|
|
RUBY_MEMORY_VIEW_ANY_CONTIGUOUS = RUBY_MEMORY_VIEW_ROW_MAJOR | RUBY_MEMORY_VIEW_COLUMN_MAJOR,
|
|
|
|
RUBY_MEMORY_VIEW_INDIRECT = (1<<6) | RUBY_MEMORY_VIEW_STRIDES,
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char format;
|
|
|
|
unsigned native_size_p: 1;
|
|
|
|
unsigned little_endian_p: 1;
|
|
|
|
size_t offset;
|
|
|
|
size_t size;
|
|
|
|
size_t repeat;
|
|
|
|
} rb_memory_view_item_component_t;
|
|
|
|
|
|
|
|
typedef struct {
|
2020-12-24 11:47:09 -05:00
|
|
|
/* The original object that has the memory exported via this memory view. */
|
2020-09-25 07:32:02 -04:00
|
|
|
VALUE obj;
|
|
|
|
|
|
|
|
/* The pointer to the exported memory. */
|
|
|
|
void *data;
|
|
|
|
|
|
|
|
/* The number of bytes in data. */
|
2020-12-22 10:33:24 -05:00
|
|
|
ssize_t byte_size;
|
2020-09-25 07:32:02 -04:00
|
|
|
|
2020-12-22 03:33:14 -05:00
|
|
|
/* true for readonly memory, false for writable memory. */
|
2020-10-05 23:00:16 -04:00
|
|
|
bool readonly;
|
2020-09-25 07:32:02 -04:00
|
|
|
|
2020-12-23 19:32:31 -05:00
|
|
|
/* A string to describe the format of an element, or NULL for unsigned bytes.
|
|
|
|
* The format string is a sequence of the following pack-template specifiers:
|
2020-09-25 07:32:02 -04:00
|
|
|
*
|
2020-09-25 08:32:00 -04:00
|
|
|
* c, C, s, s!, S, S!, n, v, i, i!, I, I!, l, l!, L, L!,
|
|
|
|
* N, V, f, e, g, q, q!, Q, Q!, d, E, G, j, J, x
|
2020-09-25 07:32:02 -04:00
|
|
|
*
|
|
|
|
* For example, "dd" for an element that consists of two double values,
|
|
|
|
* and "CCC" for an element that consists of three bytes, such as
|
2020-12-23 19:32:31 -05:00
|
|
|
* an RGB color triplet.
|
2020-09-25 07:32:02 -04:00
|
|
|
*
|
|
|
|
* Also, the value endianness can be explicitly specified by '<' or '>'
|
|
|
|
* following a value type specifier.
|
2020-09-25 08:32:00 -04:00
|
|
|
*
|
|
|
|
* The items are packed contiguously. When you emulate the alignment of
|
|
|
|
* structure members, put '|' at the beginning of the format string,
|
|
|
|
* like "|iqc". On x86_64 Linux ABI, the size of the item by this format
|
|
|
|
* is 24 bytes instead of 13 bytes.
|
2020-09-25 07:32:02 -04:00
|
|
|
*/
|
|
|
|
const char *format;
|
|
|
|
|
|
|
|
/* The number of bytes in each element.
|
|
|
|
* item_size should equal to rb_memory_view_item_size_from_format(format). */
|
|
|
|
ssize_t item_size;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
/* The array of rb_memory_view_item_component_t that describes the
|
2020-12-09 10:24:36 -05:00
|
|
|
* item structure. rb_memory_view_prepare_item_desc and
|
|
|
|
* rb_memory_view_get_item allocate this memory if needed,
|
|
|
|
* and rb_memory_view_release frees it. */
|
2020-12-22 10:43:26 -05:00
|
|
|
const rb_memory_view_item_component_t *components;
|
2020-09-25 07:32:02 -04:00
|
|
|
|
|
|
|
/* The number of components in an item. */
|
2020-12-09 10:24:36 -05:00
|
|
|
size_t length;
|
2020-09-25 07:32:02 -04:00
|
|
|
} item_desc;
|
|
|
|
|
|
|
|
/* The number of dimension. */
|
2020-10-01 19:04:25 -04:00
|
|
|
ssize_t ndim;
|
2020-09-25 07:32:02 -04:00
|
|
|
|
|
|
|
/* ndim size array indicating the number of elements in each dimension.
|
|
|
|
* This can be NULL when ndim == 1. */
|
2020-12-22 10:43:26 -05:00
|
|
|
const ssize_t *shape;
|
2020-09-25 07:32:02 -04:00
|
|
|
|
|
|
|
/* ndim size array indicating the number of bytes to skip to go to the
|
|
|
|
* next element in each dimension. */
|
2020-12-22 10:43:26 -05:00
|
|
|
const ssize_t *strides;
|
2020-09-25 07:32:02 -04:00
|
|
|
|
|
|
|
/* The offset in each dimension when this memory view exposes a nested array.
|
|
|
|
* Or, NULL when this memory view exposes a flat array. */
|
2020-12-22 10:43:26 -05:00
|
|
|
const ssize_t *sub_offsets;
|
2020-09-25 07:32:02 -04:00
|
|
|
|
|
|
|
/* the private data for managing this exported memory */
|
|
|
|
void *const private;
|
|
|
|
} rb_memory_view_t;
|
|
|
|
|
2020-12-22 03:33:14 -05:00
|
|
|
typedef bool (* rb_memory_view_get_func_t)(VALUE obj, rb_memory_view_t *view, int flags);
|
|
|
|
typedef bool (* rb_memory_view_release_func_t)(VALUE obj, rb_memory_view_t *view);
|
|
|
|
typedef bool (* rb_memory_view_available_p_func_t)(VALUE obj);
|
2020-09-25 07:32:02 -04:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
rb_memory_view_get_func_t get_func;
|
|
|
|
rb_memory_view_release_func_t release_func;
|
|
|
|
rb_memory_view_available_p_func_t available_p_func;
|
|
|
|
} rb_memory_view_entry_t;
|
|
|
|
|
|
|
|
RBIMPL_SYMBOL_EXPORT_BEGIN()
|
|
|
|
|
|
|
|
/* memory_view.c */
|
|
|
|
bool rb_memory_view_register(VALUE klass, const rb_memory_view_entry_t *entry);
|
|
|
|
|
2020-10-05 23:18:55 -04:00
|
|
|
RBIMPL_ATTR_PURE()
|
2020-10-05 23:00:16 -04:00
|
|
|
bool rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view);
|
2020-10-05 23:18:55 -04:00
|
|
|
RBIMPL_ATTR_PURE()
|
2020-10-05 23:00:16 -04:00
|
|
|
bool rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view);
|
2020-10-05 23:18:55 -04:00
|
|
|
RBIMPL_ATTR_NOALIAS()
|
2020-10-05 23:00:16 -04:00
|
|
|
void rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides);
|
2020-10-05 23:18:55 -04:00
|
|
|
RBIMPL_ATTR_NOALIAS()
|
2020-12-22 03:33:14 -05:00
|
|
|
bool rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly);
|
2020-09-25 07:32:02 -04:00
|
|
|
ssize_t rb_memory_view_parse_item_format(const char *format,
|
|
|
|
rb_memory_view_item_component_t **members,
|
2020-12-07 12:01:31 -05:00
|
|
|
size_t *n_members, const char **err);
|
2020-09-25 07:32:02 -04:00
|
|
|
ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err);
|
|
|
|
void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices);
|
2020-12-07 12:01:31 -05:00
|
|
|
VALUE rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members);
|
2020-12-10 07:41:47 -05:00
|
|
|
void rb_memory_view_prepare_item_desc(rb_memory_view_t *view);
|
2020-12-09 10:24:36 -05:00
|
|
|
VALUE rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices);
|
2020-09-25 07:32:02 -04:00
|
|
|
|
2020-12-22 03:33:14 -05:00
|
|
|
bool rb_memory_view_available_p(VALUE obj);
|
|
|
|
bool rb_memory_view_get(VALUE obj, rb_memory_view_t* memory_view, int flags);
|
|
|
|
bool rb_memory_view_release(rb_memory_view_t* memory_view);
|
2020-09-25 07:32:02 -04:00
|
|
|
|
2020-11-30 00:53:13 -05:00
|
|
|
/* for testing */
|
|
|
|
RUBY_EXTERN VALUE rb_memory_view_exported_object_registry;
|
|
|
|
RUBY_EXTERN const rb_data_type_t rb_memory_view_exported_object_registry_data_type;
|
|
|
|
|
2020-09-25 07:32:02 -04:00
|
|
|
RBIMPL_SYMBOL_EXPORT_END()
|
|
|
|
|
2020-10-05 23:18:55 -04:00
|
|
|
RBIMPL_ATTR_PURE()
|
2020-10-05 23:13:21 -04:00
|
|
|
static inline bool
|
|
|
|
rb_memory_view_is_contiguous(const rb_memory_view_t *view)
|
|
|
|
{
|
|
|
|
if (rb_memory_view_is_row_major_contiguous(view)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (rb_memory_view_is_column_major_contiguous(view)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-25 07:32:02 -04:00
|
|
|
#endif /* RUBY_BUFFER_H */
|