Exemple #1
0
int luaC_array__call(lua_State *L)
{
  struct Array *A = lunum_checkarray1(L, 1);
  int nind = lua_gettop(L) - 1;

  if (nind != A->ndims) {
    luaL_error(L, "wrong number of indices (%d) for array of dimension %d",
               nind, A->ndims);
    return 0;
  }
  const int Nd = A->ndims;
  int *stride = (int*) malloc(A->ndims * sizeof(int));
  stride[Nd-1] = 1;

  for (int d=Nd-2; d>=0; --d) {
    stride[d] = stride[d+1] * A->shape[d+1];
  }

  int m = 0;
  for (int d=0; d<A->ndims; ++d) {
    int i = lua_tointeger(L, d+2);
    m += i*stride[d];
  }

  _push_value(L, A->dtype, (char*)A->data + m*array_sizeof(A->dtype));
  free(stride);

  return 1;
}
Exemple #2
0
static int luaC_lunum_slice(lua_State *L)
{

  // The first part of this function extracts a slice of the array 'A' according
  // to the convention start:stop:skip. The result is a contiguous array 'B'
  // having the same number of dimensions as 'A'.
  // ---------------------------------------------------------------------------
  size_t Nd0_t, Nd1_t, Nd2_t, Nd3_t;

  const Array *A = lunum_checkarray1(L, 1); // the array to resize
  size_t *start   = (size_t*) lunum_checkarray2(L, 2, ARRAY_TYPE_SIZE_T, &Nd0_t);
  size_t *stop    = (size_t*) lunum_checkarray2(L, 3, ARRAY_TYPE_SIZE_T, &Nd1_t);
  size_t *skip    = (size_t*) lunum_checkarray2(L, 4, ARRAY_TYPE_SIZE_T, &Nd2_t);
  size_t *squeeze = (size_t*) lunum_checkarray2(L, 5, ARRAY_TYPE_SIZE_T, &Nd3_t);

  int Nd0 = (int)Nd0_t, Nd1 = (int)Nd1_t, Nd2 = (int)Nd2_t, Nd3 = (int)Nd3_t;


  if (Nd0 != A->ndims || Nd1 != A->ndims || Nd2 != A->ndims || Nd3 != A->ndims) {
    return luaL_error(L, "slice has wrong number of dimensions for array");
  }

  for (int d=0; d<A->ndims; ++d) {
    if (start[d] < 0 || stop[d] > A->shape[d]) {
      return luaL_error(L, "slice not within array extent");
    }
  }
  Array B = array_new_from_slice(A, start, stop, skip, Nd0);


  // The rest of this function deals with squeezing out the size-1 dimensions of
  // 'B' which are marked by the 'squeeze' array.
  // ---------------------------------------------------------------------------
  size_t Nd_new = 0;
  for (int d=0; d<Nd0; ++d) Nd_new += !squeeze[d];

  // In case we're left with a 0-dimensional (scalar) slice
  if (Nd_new == 0) {
    _push_value(L, B.dtype, B.data);
    return 1;
  }
  // In case there are any dims to squeeze out
  else if (Nd_new != Nd0) {

    size_t *shape_new = (size_t*) malloc(Nd_new * sizeof(size_t));
    for (int d=0,e=0; d<Nd0; ++d) {
      if (B.shape[d] > 1 || !squeeze[d]) {
	shape_new[e] = B.shape[d];
	++e;
      }
    }
    array_resize_t(&B, shape_new, Nd_new);
    free(shape_new);
  }

  lunum_pusharray1(L, &B);
  return 1;
}
Exemple #3
0
/*
	lightuserdata pattern
	string format "ixrsmb"
	integer size
	lightuserdata buffer
	integer buffer_len
 */
static int
_pattern_unpack(lua_State *L) {
	struct pbc_pattern * pat = (struct pbc_pattern *)checkuserdata(L, 1);
	if (pat == NULL) {
		return luaL_error(L, "unpack pattern is NULL");
	}
	size_t format_sz = 0;
	const char * format = lua_tolstring(L,2,&format_sz);
	int size = lua_tointeger(L,3);
	struct pbc_slice slice;
	if (lua_isstring(L,4)) {
		size_t buffer_len = 0;
		const char *buffer = luaL_checklstring(L,4,&buffer_len);
		slice.buffer = (void *)buffer;
		slice.len = buffer_len;
	} else {
		if (!lua_isuserdata(L,4)) {
			return luaL_error(L, "Need a userdata");
		}
		slice.buffer = lua_touserdata(L,4);
		slice.len = luaL_checkinteger(L,5);
	}
	
	char * temp = (char *)alloca(size);
	int ret = pbc_pattern_unpack(pat, &slice, temp);
	if (ret < 0) {
		return 0;
	}
	lua_checkstack(L, format_sz + 3);
	int i;
	char * ptr = temp;
	bool array = false;
	for (i=0;i<format_sz;i++) {
		char type = format[i];
		if (type >= 'a' && type <='z') {
			ptr = (char *)_push_value(L,ptr,type);
		} else {
			array = true;
			int n = pbc_array_size((struct _pbc_array *)ptr);
			lua_createtable(L,n,0);
			int j;
			for (j=0;j<n;j++) {
				_push_array(L,(struct _pbc_array *)ptr, type, j);
			}
			ptr += sizeof(pbc_array);
		}
	}
	if (array) {
		pbc_pattern_close_arrays(pat, temp);
	}
	return format_sz;
}
Exemple #4
0
/*
	lightuserdata pattern
	string format "ixrsmb"
	integer size
	lightuserdata buffer
	integer buffer_len
 */
static int
_pattern_unpack(lua_State *L) {
	struct pbc_pattern * pat = lua_touserdata(L, 1);
	size_t format_sz = 0;
	const char * format = lua_tolstring(L,2,&format_sz);
	int size = lua_tointeger(L,3);
	struct pbc_slice slice;
	if (lua_isstring(L,4)) {
		size_t buffer_len = 0;
		const char *buffer = lua_tolstring(L,4,&buffer_len);
		slice.buffer = (void *)buffer;
		slice.len = buffer_len;
	} else {
		slice.buffer = lua_touserdata(L,4);
		slice.len = lua_tointeger(L,5);
	}
	
	char temp[size];
	int ret = pbc_pattern_unpack(pat, &slice, temp);
	if (ret < 0) 
		return 0;
	lua_checkstack(L, format_sz + 3);
	int i;
	char * ptr = temp;
	bool array = false;
	for (i=0;i<format_sz;i++) {
		char type = format[i];
		if (type >= 'a' && type <='z') {
			ptr = _push_value(L,ptr,type);
		} else {
			array = true;
			int n = pbc_array_size((void *)ptr);
			lua_createtable(L,n,0);
			int j;
			for (j=0;j<n;j++) {
				_push_array(L,(void *)ptr, type, j);
			}
		}
	}
	if (array) {
		pbc_pattern_close_arrays(pat, temp);
	}
	return format_sz;
}
Exemple #5
0
static int luaC_array__call(lua_State *L)
{
  Array *A = lunum_checkarray1(L, 1);

  /* slicing done here to split concerns between indexing and slicing */
  if (lua_type(L, 2) == LUA_TTABLE || lua_type(L, 2) == LUA_TSTRING) {
    /* make slice */
    lua_getglobal(L, "lunum");
    lua_getfield(L, -1, "__build_slice");
    lua_insert(L, 1);
    lua_settop(L, 3);
    lua_call(L, 2, 1);

    return 1;
  }
  /* index */
  const int nind = lua_gettop(L) - 1;

  if (nind != A->ndims) {
    return luaL_error(L, "wrong number of indices (%d) for array of dimension %d",
               nind, A->ndims);
    return 0;
  }

  int isnum;
  size_t m = 0;
  for (int d=0; d < nind; ++d) {
    const size_t i = lua_tointegerx(L, d+2, &isnum);
    if (i >= A->shape[d]) {
      return luaL_error(L, "array indexed out of bounds (%d) on dimension %d of size %d",
                 i, d, A->shape[d]);
    } else if (!isnum) {
      return luaL_error(L, "non-integer index encountered");
    }
    m = m * A->shape[d] + i;
  }
  _push_value(L, A->dtype, (char*)A->data + m*array_sizeof(A->dtype));

  return 1;
}
Exemple #6
0
static int luaC_array__index(lua_State *L)
{
  Array *A = lunum_checkarray1(L, 1);

  // Figure out what is the format of the input index. If it's a number or a
  // table of numbers, then pass it along to _get_index. If it's an array of bools,
  // then use it as a mask.
  // ---------------------------------------------------------------------------

  if (lunum_hasmetatable(L, 2, "array")) {
    Array *M = lunum_checkarray1(L, 2);
    if (M->dtype != ARRAY_TYPE_BOOL) {
      return luaL_error(L, "index array must be of type bool");
    }
    Array B = array_new_from_mask(A, M);
    lunum_pusharray1(L, &B);
    return 1;
  }

  /* try to index into array */
  int success;
  const size_t m = _get_index(L, A, &success);
  if (success) {
    _push_value(L, A->dtype, (char*)A->data + array_sizeof(A->dtype)*m);
    return 1;
  }

  /* check metatable */
  lua_getmetatable(L, 1);
  lua_pushvalue(L, 2);
  if (lua_gettable(L, -2) != LUA_TNIL) {
    return 1;
  }

  return 0;
}
Exemple #7
0
int luaC_array__index(lua_State *L)
{
  struct Array *A = lunum_checkarray1(L, 1);

  // Figure out what is the format of the input index. If it's a number or a
  // table of numbers, then pass it along to _get_index. If it's a table of
  // tables or numbers, then assume it's a slice. If it's an array of bools,
  // then use it as a mask.
  // ---------------------------------------------------------------------------

  if (lunum_hasmetatable(L, 2, "array")) {
    struct Array *M = lunum_checkarray1(L, 2);
    if (M->dtype != ARRAY_TYPE_BOOL) {
      luaL_error(L, "index array must be of type bool");
    }
    struct Array B = array_new_from_mask(A, M);
    lunum_pusharray1(L, &B);
    return 1;
  }
  else if (lua_type(L, 2) == LUA_TTABLE || lua_type(L, 2) == LUA_TSTRING) {

    lua_getglobal(L, "lunum");
    lua_getfield(L, -1, "__build_slice");
    lua_remove(L, -2);
    lua_pushvalue(L, 1);
    lua_pushvalue(L, 2);
    lua_call(L, 2, 1);

    return 1;
  }

  const int m = _get_index(L, A);
  _push_value(L, A->dtype, (char*)A->data + array_sizeof(A->dtype)*m);

  return 1;
}