Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constant Arrays #152

Open
brandonbloom opened this issue Jan 17, 2016 · 8 comments
Open

Constant Arrays #152

brandonbloom opened this issue Jan 17, 2016 · 8 comments

Comments

@brandonbloom
Copy link
Contributor

The documentation reads:

Terra constants represent constant values used in Terra code. For instance, if you want to create a lookup table for the sin function, you might first use Lua to calculate the values and then create a constant Terra array of floating point numbers to hold the values.

The constant function seems to work just fine for integers I've tried it on. However, I can't figure out how to make this work with arrays. I'd expect this to work:

$ terra

Terra -- A low-level counterpart to Lua

Stanford University
zdevito@stanford.edu

> x = constant(terralib.types.array(int, 3), {0,1,2})
src/terralib.lua:4440: bad argument #1 to 'cast' (invalid C type)
stack traceback:
    [C]: in function 'cast'
    src/terralib.lua:4440: in function 'constant'
    [string "stdin"]:1: in main chunk

Am I missing something?

@zdevito
Copy link
Collaborator

zdevito commented Jan 17, 2016

Here is some example code to do this. I don't remember offhand why what you
wrote doesn't work:

local N = 32
local tbl = terralib.new(float[N])
for i = 1,N do
tbl[i-1] = math.sin( 2 * math.pi * (i-1)/N)
end

local ctable = terralib.constant(tbl)

terra sintable(a : float) : float
var idx = int(a / (2 * math.pi) * N)

return ctable[idx]
end

sintable:disas()

print(sintable(0))
print(sintable(math.pi/4))

On Sat, Jan 16, 2016 at 4:00 PM, Brandon Bloom notifications@github.com
wrote:

The documentation reads:

Terra constants represent constant values used in Terra code. For
instance, if you want to create a lookup table for the sin function, you
might first use Lua to calculate the values and then create a constant
Terra array of floating point numbers to hold the values.

The constant function seems to work just fine for integers I've tried it
on. However, I can't figure out how to make this work with arrays. I'd
expect this to work:

$ terra

Terra -- A low-level counterpart to Lua

Stanford Universityzdevito@stanford.edu

x = constant(terralib.types.array(int, 3), {0,1,2})
src/terralib.lua:4440: bad argument #1 to 'cast' (invalid C type)
stack traceback:
[C]: in function 'cast'
src/terralib.lua:4440: in function 'constant'
[string "stdin"]:1: in main chunk

Am I missing something?


Reply to this email directly or view it on GitHub
#152.

@brandonbloom
Copy link
Contributor Author

Thanks! I'll leave this ticket open in case you ever want to dig in to the nature of my problem.

I've got to say, this project is fantastic. I've been writing some C, doing some gnarly text-template metaprogramming, and toying with Rust every now and again. I was able to pick up Lua in one evening and Terra the next, and was instantly productive with some pretty sophisticated metaprogramming. Thanks!

@Qix-
Copy link

Qix- commented Jul 10, 2018

I just wasted about 30 minutes figuring out how to make constant sized arrays of a specific base type - @brandonbloom's #152 (comment) taught me terralib.types.array(base_type, num_entries) and I want to cry a little. I came here to complain a little about the inability to create such types and found this thread ._.

This is off-topic a bit, but if anyone is interested in a completely ridiculous way to create a sized array type, here you go:

local function instfor(typ)
	-- evil little C trick that translates nicely into Terra
	return (`@([&typ](nil)))
end

local function sized_array_type(base_type, num_entries)
	-- this is so ridiculous, but it works: returns `base_type[num_entries]` as a type.
	local entries = {}
	for i=1,num_entries do table.insert(entries, instfor(base_type)) end
	return (`array([entries])):gettype()
end

Terra is pretty neat (:

@capr
Copy link
Member

capr commented Jan 5, 2019

Is there any way to make a constant array directly out of a Lua array without creating the temporary cdata buffer?

@elliottslaughter
Copy link
Member

On newer versions of Terra the following should work:

> =terralib.constant(`array([{1, 2, 3}]))
constant <constant> : int32[3] = array(1, 2, 3)

This is basically making a quote with the list of elements, and passing that to terralib.constant.

@capr
Copy link
Member

capr commented Jan 6, 2019

@elliottslaughter doesn't that still use unpack() and is thus limited to some 200 args? I had that problem before.

@elliottslaughter
Copy link
Member

Hm, that does seem to be the case. At least on my machine, the limit is 7999 args. Not sure why it's that exact value, but beyond that I get:

src/terralib.lua:2572: too many results to unpack
stack traceback:
	[C]: in function 'unpack'
	src/terralib.lua:2572: in function 'docheck'
	src/terralib.lua:3030: in function 'checkexp'
	src/terralib.lua:2557: in function 'checkexpressions'
	src/terralib.lua:2724: in function 'docheck'
	src/terralib.lua:3030: in function 'checkexp'
	src/terralib.lua:3323: in function 'typecheck'
	src/terralib.lua:1154: in function 'definequote'
	terra_array_constant.t:9: in main chunk

with the program:

function range(i, j)
  local result = terralib.newlist()
  for v = i, j do
    result:insert(v)
  end
  return result
end

print(terralib.constant(`array([range(1, 8000)])))

However, I'm guessing this is just an implementation detail. I don't see anything in the above code that would indicate that it has to be implemented with unpack. So in theory Terra could be fixed to lift this limitation.

@elliottslaughter
Copy link
Member

In case anyone comes here looking for a workaround, I'm copying what @zdevito posted up earlier in the threat (cleaned up slightly for presentation):

local N = 8000
local t = terralib.new(float[N])
for i = 1,N do
  t[i-1] = i
end
local c = terralib.constant(t)

terra f(x : int)
  return c[x]
end
print(f(0))
print(f(1))
print(f(2))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants