Added comments
This commit is contained in:
228
tensor.c
228
tensor.c
@@ -2,11 +2,19 @@
|
|||||||
|
|
||||||
tensor tensor_new(void)
|
tensor tensor_new(void)
|
||||||
{
|
{
|
||||||
|
/* Creates a new tensor struct and returns it.
|
||||||
|
*
|
||||||
|
* @return A tensor (pointer to memory for a _tensor struct)
|
||||||
|
*/
|
||||||
return calloc(1, sizeof(struct _tensor));
|
return calloc(1, sizeof(struct _tensor));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tensor_destroy(tensor t)
|
void tensor_destroy(tensor t)
|
||||||
{
|
{
|
||||||
|
/* Destroys a tensor struct by free its memory.
|
||||||
|
*
|
||||||
|
* @param t The tensor that should be deleted
|
||||||
|
*/
|
||||||
if (!tensor_is_empty(t)) {
|
if (!tensor_is_empty(t)) {
|
||||||
free(t->size);
|
free(t->size);
|
||||||
free(t->elements);
|
free(t->elements);
|
||||||
@@ -17,11 +25,24 @@ void tensor_destroy(tensor t)
|
|||||||
|
|
||||||
bool tensor_is_empty(const tensor t)
|
bool tensor_is_empty(const tensor t)
|
||||||
{
|
{
|
||||||
|
/* Checks whether a tensor is empty.
|
||||||
|
*
|
||||||
|
* @param t The tensor to check
|
||||||
|
*
|
||||||
|
* @return true when the tensor is empty, false otherwise
|
||||||
|
*/
|
||||||
return t->elements == NULL || t->size == NULL;
|
return t->elements == NULL || t->size == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tensor_is_equal(const tensor t1, const tensor t2)
|
bool tensor_is_equal(const tensor t1, const tensor t2)
|
||||||
{
|
{
|
||||||
|
/* Checks whether two tensor are equal.
|
||||||
|
*
|
||||||
|
* @param t1 The first tensor
|
||||||
|
* @param t2 The seconds tensor
|
||||||
|
*
|
||||||
|
* @return true when the two tensors are equal, false otherwise
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t1));
|
assert(!tensor_is_empty(t1));
|
||||||
assert(!tensor_is_empty(t2));
|
assert(!tensor_is_empty(t2));
|
||||||
|
|
||||||
@@ -36,19 +57,34 @@ bool tensor_is_equal(const tensor t1, const tensor t2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t _tensor_check_size(const uint32_t *size, uint8_t rank)
|
bool _tensor_check_size(const uint32_t *size, uint8_t rank)
|
||||||
{
|
{
|
||||||
|
/* Checks whether a size array is valid.
|
||||||
|
*
|
||||||
|
* @param size A size array
|
||||||
|
* @param rank The length of the size array
|
||||||
|
*
|
||||||
|
* @return true when the size is valid, false otherwise
|
||||||
|
*/
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
if(rank < 0) return 0;
|
if(rank < 0) return false;
|
||||||
for(i = 0; i < rank; i++) {
|
for(i = 0; i < rank; i++) {
|
||||||
if(size[i] < 1) return 0;
|
if(size[i] < 1) return false;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t _tensor_set_size(tensor t, const uint32_t *size, uint8_t rank)
|
bool _tensor_set_size(tensor t, const uint32_t *size, uint8_t rank)
|
||||||
{
|
{
|
||||||
/* Sets the size of a Tensor. During this process all data in the tensor t is lost. */
|
/* Sets the size of a Tensor. During this process all data in the tensor t
|
||||||
|
* is lost.
|
||||||
|
*
|
||||||
|
* @param t The tensor that should be changed
|
||||||
|
* @param size The final size of the tensor t
|
||||||
|
* @param rank The length of size
|
||||||
|
*
|
||||||
|
* @return true if the process was successful, false when an error occured
|
||||||
|
*/
|
||||||
|
|
||||||
uint32_t *temp_size;
|
uint32_t *temp_size;
|
||||||
uint32_t *temp_index_offset;
|
uint32_t *temp_index_offset;
|
||||||
@@ -56,7 +92,7 @@ uint8_t _tensor_set_size(tensor t, const uint32_t *size, uint8_t rank)
|
|||||||
uint8_t i, j;
|
uint8_t i, j;
|
||||||
uint32_t num_elem = 1;
|
uint32_t num_elem = 1;
|
||||||
|
|
||||||
if(!_tensor_check_size(size, rank)) return 0;
|
if(!_tensor_check_size(size, rank)) return false;
|
||||||
|
|
||||||
/* Try allocating memory for the size/ index_offset array of the tensor */
|
/* Try allocating memory for the size/ index_offset array of the tensor */
|
||||||
for(i = 0; i < rank; i++) {
|
for(i = 0; i < rank; i++) {
|
||||||
@@ -68,7 +104,7 @@ uint8_t _tensor_set_size(tensor t, const uint32_t *size, uint8_t rank)
|
|||||||
if((temp_size == NULL && rank != 0) || (temp_index_offset == NULL && rank != 0) || temp_elements == NULL) {
|
if((temp_size == NULL && rank != 0) || (temp_index_offset == NULL && rank != 0) || temp_elements == NULL) {
|
||||||
free(temp_size);
|
free(temp_size);
|
||||||
free(temp_index_offset);
|
free(temp_index_offset);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Freeing old memory. */
|
/* Freeing old memory. */
|
||||||
@@ -92,11 +128,20 @@ uint8_t _tensor_set_size(tensor t, const uint32_t *size, uint8_t rank)
|
|||||||
t->elements = temp_elements;
|
t->elements = temp_elements;
|
||||||
t->num_elem = num_elem;
|
t->num_elem = num_elem;
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tensor_set(tensor t, const uint32_t *index, dtype val)
|
bool tensor_set(tensor t, const uint32_t *index, dtype val)
|
||||||
{
|
{
|
||||||
|
/* Set the value at a index of a tensor.
|
||||||
|
*
|
||||||
|
* @param t The tensor to change
|
||||||
|
* @param index The index of the value that should change, the length of
|
||||||
|
* this array is defined by the rank of t
|
||||||
|
* @param val The updated value
|
||||||
|
*
|
||||||
|
* @return true if the change was successful, false otherwise
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t));
|
assert(!tensor_is_empty(t));
|
||||||
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@@ -104,20 +149,30 @@ uint8_t tensor_set(tensor t, const uint32_t *index, dtype val)
|
|||||||
|
|
||||||
if(t->rank == 0) {
|
if(t->rank == 0) {
|
||||||
t->elements[0] = val;
|
t->elements[0] = val;
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < t->rank; i++) {
|
for(i = 0; i < t->rank; i++) {
|
||||||
if(t->size[i] <= index[i]) return 0;
|
if(t->size[i] <= index[i]) return false;
|
||||||
offset += t->index_offsets[i] * index[i];
|
offset += t->index_offsets[i] * index[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
t->elements[offset] = val;
|
t->elements[offset] = val;
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dtype tensor_get(const tensor t, const uint32_t *index, uint8_t *success)
|
dtype tensor_get(const tensor t, const uint32_t *index, bool *success)
|
||||||
{
|
{
|
||||||
|
/* Gets a value at a index from a tensor.
|
||||||
|
*
|
||||||
|
* @param t The tensor from which to get the value from
|
||||||
|
* @param index The index of the value to get, the length of this array is
|
||||||
|
* defined by the rank of t
|
||||||
|
* @param success Is set according to the exit status of the function, if it
|
||||||
|
* is NULL it is ignored
|
||||||
|
*
|
||||||
|
* @return The retrieved value, DTYPE_NULL in case of an error
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t));
|
assert(!tensor_is_empty(t));
|
||||||
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@@ -127,98 +182,156 @@ dtype tensor_get(const tensor t, const uint32_t *index, uint8_t *success)
|
|||||||
|
|
||||||
for(i = 0; i < t->rank; i++) {
|
for(i = 0; i < t->rank; i++) {
|
||||||
if(t->size[i] <= index[i]) {
|
if(t->size[i] <= index[i]) {
|
||||||
if(success != NULL) *success = 0;
|
if(success != NULL) *success = false;
|
||||||
return 0;
|
return DTYPE_ZERO;
|
||||||
}
|
}
|
||||||
offset += t->index_offsets[i] * index[i];
|
offset += t->index_offsets[i] * index[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(success != NULL) *success = 1;
|
if(success != NULL) *success = true;
|
||||||
return t->elements[offset];
|
return t->elements[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tensor_init_one(tensor t, uint8_t rank, const uint32_t *size)
|
bool tensor_init_one(tensor t, const uint32_t *size, uint8_t rank)
|
||||||
{
|
{
|
||||||
|
/* Inits (sets the size) and filles a tensor with ones.
|
||||||
|
*
|
||||||
|
* @param t The tensor to fill
|
||||||
|
* @param size The final size of the tensor t
|
||||||
|
* @param rank The length of size array
|
||||||
|
*
|
||||||
|
* @return true when successful, false otherwise
|
||||||
|
*/
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if(!_tensor_set_size(t, size, rank)) return 0;
|
if(!_tensor_set_size(t, size, rank)) return false;
|
||||||
for(i = 0; i < t->num_elem; i++) {
|
for(i = 0; i < t->num_elem; i++) {
|
||||||
t->elements[i] = DTYPE_ONE;
|
t->elements[i] = DTYPE_ONE;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tensor_init_zero(tensor t, uint8_t rank, const uint32_t *size)
|
bool tensor_init_zero(tensor t, const uint32_t *size, uint8_t rank)
|
||||||
{
|
{
|
||||||
|
/* Inits (sets the size) and filles a tensor with zeros.
|
||||||
|
*
|
||||||
|
* @param t The tensor to fill
|
||||||
|
* @param size The final size of the tensor t
|
||||||
|
* @param rank The length of size array
|
||||||
|
*
|
||||||
|
* @return true when successful, false otherwise
|
||||||
|
*/
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if(!_tensor_set_size(t, size, rank)) return 0;
|
if(!_tensor_set_size(t, size, rank)) return false;
|
||||||
for(i = 0; i < t->num_elem; i++) {
|
for(i = 0; i < t->num_elem; i++) {
|
||||||
t->elements[i] = DTYPE_ZERO;
|
t->elements[i] = DTYPE_ZERO;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tensor_init_rand(tensor t, uint8_t rank, const uint32_t *size, dtype max)
|
bool tensor_init_rand(tensor t, const uint32_t *size, uint8_t rank, dtype max)
|
||||||
{
|
{
|
||||||
|
/* Inits (sets the size) and filles a tensor with random values below or
|
||||||
|
* equal to the max value.
|
||||||
|
*
|
||||||
|
* @param t The tensor to fill
|
||||||
|
* @param size The final size of the tensor t
|
||||||
|
* @param rank The length of size array
|
||||||
|
* @param max The maximal value filled in
|
||||||
|
*
|
||||||
|
* @return true when successful, false otherwise
|
||||||
|
*/
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
static long last_seed;
|
static long last_seed;
|
||||||
last_seed += time(NULL) * 200 + rand();
|
last_seed += time(NULL) * 200 + rand();
|
||||||
srand(last_seed);
|
srand(last_seed);
|
||||||
|
|
||||||
if(!_tensor_set_size(t, size, rank)) return 0;
|
if(!_tensor_set_size(t, size, rank)) return false;
|
||||||
for(i = 0; i < t->num_elem; i++) {
|
for(i = 0; i < t->num_elem; i++) {
|
||||||
t->elements[i] = DTYPE_RAND(max);
|
t->elements[i] = DTYPE_RAND(max);
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tensor_cpy(tensor t1, const tensor t2)
|
bool tensor_cpy(tensor t1, const tensor t2)
|
||||||
{
|
{
|
||||||
|
/* Copies the contents of t2 into t1.
|
||||||
|
*
|
||||||
|
* @param t1 The tensor in which to copy the values
|
||||||
|
* @param t2 The tensor from which to copy the values
|
||||||
|
*
|
||||||
|
* @return true when successful, false otherwise
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t2));
|
assert(!tensor_is_empty(t2));
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if(!_tensor_set_size(t1, t2->size, t2->rank)) return 0;
|
if(!_tensor_set_size(t1, t2->size, t2->rank)) return false;
|
||||||
for(i = 0; i < t2->num_elem; i++) {
|
for(i = 0; i < t2->num_elem; i++) {
|
||||||
t1->elements[i] = t2->elements[i];
|
t1->elements[i] = t2->elements[i];
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tensor_add_inplace(tensor t1, const tensor t2)
|
bool tensor_add_inplace(tensor t1, const tensor t2)
|
||||||
{
|
{
|
||||||
|
/* Adds the values of t2 onto the values of t1. t1 and t2 need to have the
|
||||||
|
* same size.
|
||||||
|
*
|
||||||
|
* @param t1 The tensor on which the values of t2 are added
|
||||||
|
* @param t2 The tensor whose values are added
|
||||||
|
*
|
||||||
|
* @return true when successful, false otherwise
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t1));
|
assert(!tensor_is_empty(t1));
|
||||||
assert(!tensor_is_empty(t2));
|
assert(!tensor_is_empty(t2));
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if(t1->rank != t2->rank) return 0;
|
|
||||||
|
if(t1->rank != t2->rank) return false;
|
||||||
for(i = 0; i < t1->rank; i++) {
|
for(i = 0; i < t1->rank; i++) {
|
||||||
if(t1->size[i] != t2->size[i]) return 0;
|
if(t1->size[i] != t2->size[i]) return false;
|
||||||
}
|
}
|
||||||
for(i = 0; i < t1->num_elem; i++) {
|
for(i = 0; i < t1->num_elem; i++) {
|
||||||
t1->elements[i] = DTYPE_ADD(t1->elements[i], t2->elements[i]);
|
t1->elements[i] = DTYPE_ADD(t1->elements[i], t2->elements[i]);
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tensor_sub_inplace(tensor t1, const tensor t2)
|
bool tensor_sub_inplace(tensor t1, const tensor t2)
|
||||||
{
|
{
|
||||||
|
/* Subtracts the values of t2 from the values of t1. t1 and t2 need to have
|
||||||
|
* the same size.
|
||||||
|
*
|
||||||
|
* @param t1 The tensor from which the values of t2 are subtracted
|
||||||
|
* @param t2 The tensor whose values are subtracted
|
||||||
|
*
|
||||||
|
* @return true when successful, false otherwise
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t1));
|
assert(!tensor_is_empty(t1));
|
||||||
assert(!tensor_is_empty(t2));
|
assert(!tensor_is_empty(t2));
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if(t1->rank != t2->rank) return 0;
|
|
||||||
|
if(t1->rank != t2->rank) return false;
|
||||||
for(i = 0; i < t1->rank; i++) {
|
for(i = 0; i < t1->rank; i++) {
|
||||||
if(t1->size[i] != t2->size[i]) return 0;
|
if(t1->size[i] != t2->size[i]) return false;
|
||||||
}
|
}
|
||||||
for(i = 0; i < t1->num_elem; i++) {
|
for(i = 0; i < t1->num_elem; i++) {
|
||||||
t1->elements[i] = DTYPE_SUB(t1->elements[i], t2->elements[i]);
|
t1->elements[i] = DTYPE_SUB(t1->elements[i], t2->elements[i]);
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tensor tensor_add(const tensor t1, const tensor t2)
|
tensor tensor_add(const tensor t1, const tensor t2)
|
||||||
{
|
{
|
||||||
|
/* Adds to tensors returning the result as a tensor.
|
||||||
|
*
|
||||||
|
* @param t1 The first tensor to add
|
||||||
|
* @param t2 The second tensor to add
|
||||||
|
*
|
||||||
|
* @return The result of the operation, NULL if an error occurs
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t1));
|
assert(!tensor_is_empty(t1));
|
||||||
assert(!tensor_is_empty(t2));
|
assert(!tensor_is_empty(t2));
|
||||||
|
|
||||||
@@ -231,6 +344,13 @@ tensor tensor_add(const tensor t1, const tensor t2)
|
|||||||
|
|
||||||
tensor tensor_sub(const tensor t1, const tensor t2)
|
tensor tensor_sub(const tensor t1, const tensor t2)
|
||||||
{
|
{
|
||||||
|
/* Subtracts to tensors returning the result as a tensor.
|
||||||
|
*
|
||||||
|
* @param t1 The tensor to subtract from
|
||||||
|
* @param t2 The tensor that is subtracted
|
||||||
|
*
|
||||||
|
* @return The result of the operation, NULL if an error occurs
|
||||||
|
*/
|
||||||
assert(!tensor_is_empty(t1));
|
assert(!tensor_is_empty(t1));
|
||||||
assert(!tensor_is_empty(t2));
|
assert(!tensor_is_empty(t2));
|
||||||
|
|
||||||
@@ -244,8 +364,12 @@ tensor tensor_sub(const tensor t1, const tensor t2)
|
|||||||
|
|
||||||
void tensor_print(const tensor t)
|
void tensor_print(const tensor t)
|
||||||
{
|
{
|
||||||
|
/* Prints a tensor to stdout.
|
||||||
|
*
|
||||||
|
* @param t The tensor to print
|
||||||
|
*/
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
uint32_t *indx;
|
uint32_t *index;
|
||||||
|
|
||||||
if(tensor_is_empty(t)){
|
if(tensor_is_empty(t)){
|
||||||
printf("<empty tensor>\n");
|
printf("<empty tensor>\n");
|
||||||
@@ -285,41 +409,41 @@ void tensor_print(const tensor t)
|
|||||||
}
|
}
|
||||||
} else if (t->rank == 2) {
|
} else if (t->rank == 2) {
|
||||||
/* matix */
|
/* matix */
|
||||||
indx = malloc(sizeof(int) * 2);
|
index = malloc(sizeof(int) * 2);
|
||||||
if(t->size[0] == 1) {
|
if(t->size[0] == 1) {
|
||||||
putchar('(');
|
putchar('(');
|
||||||
indx[0] = 0;
|
index[0] = 0;
|
||||||
for(i = 0; i < t->size[1]; i++) {
|
for(i = 0; i < t->size[1]; i++) {
|
||||||
indx[1] = i;
|
index[1] = i;
|
||||||
DTYPE_PRINT(tensor_get(t, indx, NULL));
|
DTYPE_PRINT(tensor_get(t, index, NULL));
|
||||||
}
|
}
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
} else {
|
} else {
|
||||||
printf("\n/");
|
printf("\n/");
|
||||||
indx[0] = 0;
|
index[0] = 0;
|
||||||
for(i = 0; i < t->size[1]; i++) {
|
for(i = 0; i < t->size[1]; i++) {
|
||||||
indx[1] = i;
|
index[1] = i;
|
||||||
DTYPE_PRINT(tensor_get(t, indx, NULL));
|
DTYPE_PRINT(tensor_get(t, index, NULL));
|
||||||
}
|
}
|
||||||
printf("\\\n");
|
printf("\\\n");
|
||||||
for(i = 1; i < t->size[0] - 1; i++) {
|
for(i = 1; i < t->size[0] - 1; i++) {
|
||||||
putchar('|');
|
putchar('|');
|
||||||
indx[0] = i;
|
index[0] = i;
|
||||||
for(j = 0; j < t->size[1]; j++) {
|
for(j = 0; j < t->size[1]; j++) {
|
||||||
indx[1] = j;
|
index[1] = j;
|
||||||
DTYPE_PRINT(tensor_get(t, indx, NULL));
|
DTYPE_PRINT(tensor_get(t, index, NULL));
|
||||||
}
|
}
|
||||||
printf("|\n");
|
printf("|\n");
|
||||||
}
|
}
|
||||||
printf("\\");
|
printf("\\");
|
||||||
indx[0] = t->size[0] - 1;
|
index[0] = t->size[0] - 1;
|
||||||
for(i = 0; i < t->size[1]; i++) {
|
for(i = 0; i < t->size[1]; i++) {
|
||||||
indx[1] = i;
|
index[1] = i;
|
||||||
DTYPE_PRINT(tensor_get(t, indx, NULL));
|
DTYPE_PRINT(tensor_get(t, index, NULL));
|
||||||
}
|
}
|
||||||
printf("/\n");
|
printf("/\n");
|
||||||
}
|
}
|
||||||
free(indx);
|
free(index);
|
||||||
} else {
|
} else {
|
||||||
putchar('[');
|
putchar('[');
|
||||||
for(i = 0; i < t->num_elem; i++) {
|
for(i = 0; i < t->num_elem; i++) {
|
||||||
|
|||||||
21
tensor.h
21
tensor.h
@@ -42,23 +42,22 @@ void tensor_destroy(tensor t);
|
|||||||
bool tensor_is_empty(const tensor t);
|
bool tensor_is_empty(const tensor t);
|
||||||
bool tensor_is_equal(const tensor t1, const tensor t2);
|
bool tensor_is_equal(const tensor t1, const tensor t2);
|
||||||
|
|
||||||
uint8_t _tensor_check_size(const uint32_t *size, uint8_t rank);
|
bool _tensor_check_size(const uint32_t *size, uint8_t rank);
|
||||||
uint8_t _tensor_set_size(tensor t, const uint32_t *size, uint8_t rank);
|
bool _tensor_set_size(tensor t, const uint32_t *size, uint8_t rank);
|
||||||
|
|
||||||
uint8_t tensor_set(tensor t, const uint32_t *index, dtype val);
|
bool tensor_set(tensor t, const uint32_t *index, dtype val);
|
||||||
dtype tensor_get(const tensor t, const uint32_t *index, uint8_t *success);
|
dtype tensor_get(const tensor t, const uint32_t *index, bool *success);
|
||||||
|
|
||||||
uint8_t tensor_init_one(tensor t, uint8_t rank, const uint32_t *size);
|
bool tensor_init_one(tensor t, const uint32_t *size, uint8_t rank);
|
||||||
uint8_t tensor_init_zero(tensor t, uint8_t rank, const uint32_t *size);
|
bool tensor_init_zero(tensor t, const uint32_t *size, uint8_t rank);
|
||||||
uint8_t tensor_init_rand(tensor t, uint8_t rank, const uint32_t *size, dtype max);
|
bool tensor_init_rand(tensor t, const uint32_t *size, uint8_t rank, dtype max);
|
||||||
uint8_t tensor_cpy(tensor t1, const tensor t2);
|
bool tensor_cpy(tensor t1, const tensor t2);
|
||||||
|
|
||||||
uint8_t tensor_add_inplace(tensor t1, const tensor t2);
|
bool tensor_add_inplace(tensor t1, const tensor t2);
|
||||||
uint8_t tensor_sub_inplace(tensor t1, const tensor t2);
|
bool tensor_sub_inplace(tensor t1, const tensor t2);
|
||||||
tensor tensor_add(const tensor t1, const tensor t2);
|
tensor tensor_add(const tensor t1, const tensor t2);
|
||||||
tensor tensor_sub(const tensor t1, const tensor t2);
|
tensor tensor_sub(const tensor t1, const tensor t2);
|
||||||
|
|
||||||
void tensor_print(const tensor t);
|
void tensor_print(const tensor t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,11 @@ void test_tensor_is_equal(void)
|
|||||||
uint32_t s[4] = {2, 5, 3, 7};
|
uint32_t s[4] = {2, 5, 3, 7};
|
||||||
tensor t1 = tensor_new();
|
tensor t1 = tensor_new();
|
||||||
tensor t2 = tensor_new();
|
tensor t2 = tensor_new();
|
||||||
|
tensor_init_zero(t1, s, 4);
|
||||||
tensor_init_zero(t1, 4, s);
|
tensor_init_one(t2, s, 4);
|
||||||
tensor_init_one(t2, 4, s);
|
|
||||||
tensor_assert_ne(t1, t2);
|
tensor_assert_ne(t1, t2);
|
||||||
|
|
||||||
tensor_init_rand(t1, 4, s, 30);
|
tensor_init_rand(t1, s, 4, 30);
|
||||||
tensor_cpy(t2, t1);
|
tensor_cpy(t2, t1);
|
||||||
|
|
||||||
tensor_assert_eq(t1, t2);
|
tensor_assert_eq(t1, t2);
|
||||||
@@ -44,8 +43,8 @@ void test_tensor_set(void)
|
|||||||
tensor t1 = tensor_new();
|
tensor t1 = tensor_new();
|
||||||
tensor t2 = tensor_new();
|
tensor t2 = tensor_new();
|
||||||
|
|
||||||
tensor_init_rand(t1, 4, s, 30);
|
tensor_init_rand(t1, s, 4, 30);
|
||||||
tensor_init_zero(t2, 4, s);
|
tensor_init_zero(t2, s, 4);
|
||||||
|
|
||||||
for (index[0] = 0; index[0] < s[0]; ++index[0]) {
|
for (index[0] = 0; index[0] < s[0]; ++index[0]) {
|
||||||
for (index[1] = 0; index[1] < s[1]; ++index[1]) {
|
for (index[1] = 0; index[1] < s[1]; ++index[1]) {
|
||||||
@@ -70,8 +69,8 @@ void test_tensor_get(void)
|
|||||||
tensor t1 = tensor_new();
|
tensor t1 = tensor_new();
|
||||||
tensor t2 = tensor_new();
|
tensor t2 = tensor_new();
|
||||||
|
|
||||||
tensor_init_rand(t1, 4, s, 30);
|
tensor_init_rand(t1, s, 4, 30);
|
||||||
tensor_init_zero(t2, 4, s);
|
tensor_init_zero(t2, s, 4);
|
||||||
|
|
||||||
for (index[0] = 0; index[0] < s[0]; ++index[0]) {
|
for (index[0] = 0; index[0] < s[0]; ++index[0]) {
|
||||||
for (index[1] = 0; index[1] < s[1]; ++index[1]) {
|
for (index[1] = 0; index[1] < s[1]; ++index[1]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user