In [ ]:
## Basic Test
local ffi = require("ffi")
-- see if the file exists
function file_exists(file)
local f = io.open(file, "rb")
if f then f:close() end
return f ~= nil
end
-- get all lines from a file, returns an empty
-- list/table if the file does not exist
function lines_from(file)
if not file_exists(file) then return {} end
lines = {}
for line in io.lines(file) do
lines[#lines + 1] = line
end
return lines
end
local compileFile = function( file, libName)
os.execute("gcc -c -fPIC " .. file .. " -o tmp")
os.execute ("gcc tmp -shared -o " .. libName)
end
function add(a,b)
ffi.C.add(a, b)
end
local parseFile = function(retType, type1, type2, fileIn, fileOut)
print (fileOut)
os.execute(" python test.py RET=" .. retType .. " TYPE1=" .. type1 .. " TYPE2=" .. type2 .. " " .. fileIn .. " " ..fileOut)
end
local load_c_ffi = function(libName , retType, type1, type2)
local ffi = require("ffi")
-- RET * add(TYPE1* A, TYPE2* B, RET* C, int length, int nb, int blk_size)
ffi.cdef ( " int add(" .. type1 .. "* A, " .. type2 .. "* B, int length, int blk_size)")
local c = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
return c
end
local mallocAsQTable = function(size)
local ffi = require 'ffi'
local C = ffi.C
ffi.cdef([[
void * malloc(size_t size);
void free(void *ptr);
]])
local ptr = C.malloc( size )
io.stdout:write(tostring(ptr), '\n')
io.stdout:write(type(ptr), '\n')
local qTable = {}
qTable.size = size
qTable.ptr = ptr
return qTable
end
local addTwoVectors = function(vec1, vec2, vecres)
if vec1 == nil or vec2 == nil or vecres == nil then error("Vector is empty" ,2 ) end
local ffi = require("ffi")
ffi.cdef ( "int add(" .. vec1.dataType .. "* A, " .. vec2.dataType .. "* B, " .. vecres.dataType .. "* C, int length, int blk_size);")
ffi.cdef ("int initA(" .. vec1.dataType .. "*A, int length);")
ffi.cdef ("int initB(" .. vec2.dataType .. "*B, int length);")
ffi.cdef ("int writeOut(" .. vecres.dataType .. "*C, int length);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
local res = C.initA(vec1.ptr, vec1.size)
local res = C.initB(vec2.ptr, vec2.size)
local res = C.add(vec1.ptr, vec2.ptr, vecres.ptr, vec1.size, 64) -- right now assuming everything is 4 bytes
print ("My return code is " .. res)
C.writeOut(vecres.ptr, vecres.size)
end
local addTwoTables = function(table1, table2, tableres)
if table1.size ~= table2.size or table1.size ~= tableres.size then error("Expected same size Qtables", 2) end
if table1.dataType == nil or table2.dataType == nil or tableres.dataType == nil then
error("Expected data types to calculate length", 2)
end
parseFile(tableres.dataType, table1.dataType, table2.dataType, "/Users/indrajeetsingh/Dropbox/qtests/c_files/test.c", "/Users/indrajeetsingh/Dropbox/qtests/c_files/testfin.c")
compileFile("/Users/indrajeetsingh/Dropbox/qtests/c_files/testfin.c", "/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
addTwoVectors(table1, table2, tableres)
end
A = mallocAsQTable(4000)
A.dataType = "int"
B = mallocAsQTable(4000)
B.dataType = "int"
C = mallocAsQTable(4000)
C.dataType = "int"
addTwoTables(A, B, C)
In [ ]:
## Adding torch tensors but with copying data
local ffi = require("ffi")
-- see if the file exists
function file_exists(file)
local f = io.open(file, "rb")
if f then f:close() end
return f ~= nil
end
-- get all lines from a file, returns an empty
-- list/table if the file does not exist
function lines_from(file)
if not file_exists(file) then return {} end
lines = {}
for line in io.lines(file) do
lines[#lines + 1] = line
end
return lines
end
local compileFile = function( file, libName)
os.execute("gcc -c -fPIC " .. file .. " -o tmp")
os.execute ("gcc tmp -shared -o " .. libName)
end
function add(a,b)
ffi.C.add(a, b)
end
local parseFile = function(retType, type1, type2, fileIn, fileOut)
print (fileOut)
os.execute(" python test.py RET=" .. retType .. " TYPE1=" .. type1 .. " TYPE2=" .. type2 .. " " .. fileIn .. " " ..fileOut)
end
local load_c_ffi = function(libName , retType, type1, type2)
local ffi = require("ffi")
-- RET * add(TYPE1* A, TYPE2* B, RET* C, int length, int nb, int blk_size)
ffi.cdef ( " int add(" .. type1 .. "* A, " .. type2 .. "* B, int length, int blk_size)")
local c = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
return c
end
local mallocAsQTable = function(size)
local ffi = require 'ffi'
local C = ffi.C
ffi.cdef([[
void * malloc(size_t size);
void free(void *ptr);
]])
local ptr = C.malloc( size )
io.stdout:write(tostring(ptr), '\n')
io.stdout:write(type(ptr), '\n')
local qTable = {}
qTable.size = size
qTable.ptr = ptr
return qTable
end
local addTwoVectors = function(vec1, vec2, vecres)
if vec1 == nil or vec2 == nil or vecres == nil then error("Vector is empty" ,2 ) end
local ffi = require("ffi")
ffi.cdef ( "int add(" .. vec1.dataType .. "* A, " .. vec2.dataType .. "* B, " .. vecres.dataType .. "* C, int length, int blk_size);")
ffi.cdef ("int initA(" .. vec1.dataType .. "*A, int length);")
ffi.cdef ("int initB(" .. vec2.dataType .. "*B, int length);")
ffi.cdef ("int writeOut(" .. vecres.dataType .. "*C, int length);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
local res = C.initA(vec1.ptr, vec1.size)
local res = C.initB(vec2.ptr, vec2.size)
local res = C.add(vec1.ptr, vec2.ptr, vecres.ptr, vec1.size, 64) -- right now assuming everything is 4 bytes
print ("My return code is " .. res)
-- C.writeOut(vecres.ptr, vecres.size)
cdata = vecres.ptr
y = torch.IntTensor(1000)
ffi.copy(y:data(), cdata, 1000*ffi.sizeof('int'))
ffi.copy(vec1.ptr, y:data(), 1000*ffi.sizeof('int'))
C.writeOut(vec1.ptr, vec1.size)
end
local addTwoTables = function(table1, table2, tableres)
if table1.size ~= table2.size or table1.size ~= tableres.size then error("Expected same size Qtables", 2) end
if table1.dataType == nil or table2.dataType == nil or tableres.dataType == nil then
error("Expected data types to calculate length", 2)
end
parseFile(tableres.dataType, table1.dataType, table2.dataType, "/Users/indrajeetsingh/Dropbox/qtests/c_files/test.c", "/Users/indrajeetsingh/Dropbox/qtests/c_files/testfin.c")
compileFile("/Users/indrajeetsingh/Dropbox/qtests/c_files/testfin.c", "/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
addTwoVectors(table1, table2, tableres)
end
A = mallocAsQTable(4000)
A.dataType = "int"
B = mallocAsQTable(4000)
B.dataType = "int"
C = mallocAsQTable(4000)
C.dataType = "int"
cfunc = addTwoTables(A, B, C)
In [ ]:
## Copying torch data into vector but not vice versa
local ffi = require("ffi")
-- see if the file exists
function file_exists(file)
local f = io.open(file, "rb")
if f then f:close() end
return f ~= nil
end
-- get all lines from a file, returns an empty
-- list/table if the file does not exist
function lines_from(file)
if not file_exists(file) then return {} end
lines = {}
for line in io.lines(file) do
lines[#lines + 1] = line
end
return lines
end
local compileFile = function( file, libName)
os.execute("gcc -c -fPIC " .. file .. " -o tmp")
os.execute ("gcc tmp -shared -o " .. libName)
end
function add(a,b)
ffi.C.add(a, b)
end
local parseFile = function(retType, type1, type2, fileIn, fileOut)
print (fileOut)
os.execute(" python test.py RET=" .. retType .. " TYPE1=" .. type1 .. " TYPE2=" .. type2 .. " " .. fileIn .. " " ..fileOut)
end
local load_c_ffi = function(libName , retType, type1, type2)
local ffi = require("ffi")
-- RET * add(TYPE1* A, TYPE2* B, RET* C, int length, int nb, int blk_size)
ffi.cdef ( " int add(" .. type1 .. "* A, " .. type2 .. "* B, int length, int blk_size)")
local c = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
return c
end
local mallocAsQTable = function(size)
local ffi = require 'ffi'
local C = ffi.C
ffi.cdef([[
void * malloc(size_t size);
void free(void *ptr);
]])
local ptr = C.malloc( size )
io.stdout:write(tostring(ptr), '\n')
io.stdout:write(type(ptr), '\n')
local qTable = {}
qTable.size = size
qTable.ptr = ptr
return qTable
end
local addTwoVectors = function(vec1, vec2, vecres)
if vec1 == nil or vec2 == nil or vecres == nil then error("Vector is empty" ,2 ) end
local ffi = require("ffi")
ffi.cdef ( "int add(" .. vec1.dataType .. "* A, " .. vec2.dataType .. "* B, " .. vecres.dataType .. "* C, int length, int blk_size);")
ffi.cdef ("int initA(" .. vec1.dataType .. "*A, int length);")
ffi.cdef ("int initB(" .. vec2.dataType .. "*B, int length);")
ffi.cdef ("int writeOut(" .. vecres.dataType .. "*C, int length);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
local res = C.initA(vec1.ptr, vec1.size)
local res = C.initB(vec2.ptr, vec2.size)
local res = C.add(vec1.ptr, vec2.ptr, vecres.ptr, vec1.size, 64) -- right now assuming everything is 4 bytes
print ("My return code is " .. res)
--C.writeOut(vecres.ptr, vecres.size)
cdata = vecres.ptr
y = torch.IntTensor(1000):fill(5)
--ffi.copy(y:data(), cdata, 1000*ffi.sizeof('int'))
ffi.copy(vec1.ptr, y:data(), 1000*ffi.sizeof('int'))
C.writeOut(vec1.ptr, vec1.size)
end
local addTwoTables = function(table1, table2, tableres)
if table1.size ~= table2.size or table1.size ~= tableres.size then error("Expected same size Qtables", 2) end
if table1.dataType == nil or table2.dataType == nil or tableres.dataType == nil then
error("Expected data types to calculate length", 2)
end
parseFile(tableres.dataType, table1.dataType, table2.dataType, "/Users/indrajeetsingh/Dropbox/qtests/c_files/test.c", "/Users/indrajeetsingh/Dropbox/qtests/c_files/testfin.c")
compileFile("/Users/indrajeetsingh/Dropbox/qtests/c_files/testfin.c", "/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
addTwoVectors(table1, table2, tableres)
end
A = mallocAsQTable(4000)
A.dataType = "int"
B = mallocAsQTable(4000)
B.dataType = "int"
C = mallocAsQTable(4000)
C.dataType = "int"
cfunc = addTwoTables(A, B, C)
In [ ]:
s= torch.IntStorage(10):fill(1)
i = torch.IntTensor(s)
print (i)
ns = torch.IntStorage(10, s:cdata())
ni = torch.IntTensor(ns)
print (ni)
In [ ]:
## Noticed that passing pointer to torch does not use that address
local ffi = require("ffi")
local load_c_ffi = function(libName , retType, type1, type2)
local ffi = require("ffi")
-- RET * add(TYPE1* A, TYPE2* B, RET* C, int length, int nb, int blk_size)
ffi.cdef ( " int add(" .. type1 .. "* A, " .. type2 .. "* B, int length, int blk_size)")
local c = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
return c
end
local mallocAsQTable = function(size)
local ffi = require 'ffi'
local C = ffi.C
ffi.cdef([[
void * malloc(size_t size);
void free(void *ptr);
]])
local ptr = C.malloc( size )
io.stdout:write(tostring(ptr), '\n')
io.stdout:write(type(ptr), '\n')
local qTable = {}
qTable.size = size
qTable.ptr = ptr
return qTable
end
local initVec = function(vec)
local ffi = require("ffi")
ffi.cdef ("int initA(" .. vec1.dataType .. "*A, int length);")
--ffi.cdef ("int initB(" .. vec2.dataType .. "*B, int length);")
--ffi.cdef ("int writeOut(" .. vecres.dataType .. "*C, int length);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
local res = C.initA(vec.ptr, vec.size)
--local res = C.initB(vec2.ptr, vec2.size)
--local res = C.add(vec1.ptr, vec2.ptr, vecres.ptr, vec1.size, 64) -- right now assuming everything is 4 bytes
end
local printVec = function(vec)
local ffi = require("ffi")
ffi.cdef ("int writeOut(" .. "int" .. "*C, int length);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
C.writeOut(vec, 40)
end
A = mallocAsQTable(40)
print (A.ptr)
t = torch.IntStorage(10, A.ptr)
print (t:data())
print (t:cdata())
printVec(t:data())
In [1]:
--## Piping to GCC to compile
-- see if the file exists
function file_exists(file)
local f = io.open(file, "rb")
if f then f:close() end
return f ~= nil
end
local load_c_ffi = function(libName , retType, type1, type2)
local ffi = require("ffi")
-- RET * add(TYPE1* A, TYPE2* B, RET* C, int length, int nb, int blk_size)
ffi.cdef ( " int add(" .. type1 .. "* A, " .. type2 .. "* B, int length, int blk_size)")
local c = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
return c
end
local parse_and_compile = function(retType, type1, type2, fileIn, libName)
local command = "python /Users/indrajeetsingh/Dropbox/qtests/c_files/test.py RET=" .. retType .. " TYPE1=" .. type1 .. " TYPE2=" .. type2 .. " " .. fileIn .. " -"
.. " | gcc -fPIC -shared -xc -o " .. libName .. " -"
--print (command)
os.execute(command)
end
local mallocAsQTable = function(size)
local ffi = require 'ffi'
local C = ffi.C
ffi.cdef([[
void * malloc(size_t size);
void free(void *ptr);
]])
local ptr = C.malloc( size )
io.stdout:write(tostring(ptr), '\n')
io.stdout:write(type(ptr), '\n')
local qTable = {}
qTable.size = size
qTable.ptr = ptr
return qTable
end
local addTwoVectors = function(vec1, vec2, vecres)
if vec1.size ~= vec2.size or vec1.size ~= vecres.size then error("Expected same size Qtables", 2) end
if vec1.dataType == nil or vec2.dataType == nil or vecres.dataType == nil then
error("Expected data types to calculate length", 2)
end
parse_and_compile(vecres.dataType, vec1.dataType, vec2.dataType, "/Users/indrajeetsingh/Dropbox/qtests/c_files/test.c", "/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
local ffi = require("ffi")
ffi.cdef ( "int add(" .. vec1.dataType .. "* A, " .. vec2.dataType .. "* B, " .. vecres.dataType .. "* C, int length, int blk_size);")
ffi.cdef ("int initA(" .. vec1.dataType .. "*A, int length);")
ffi.cdef ("int initB(" .. vec2.dataType .. "*B, int length);")
ffi.cdef ("int writeOut(" .. vecres.dataType .. "*C, int length);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libtestfin.so")
local res = C.initA(vec1.ptr, vec1.size)
local res = C.initB(vec2.ptr, vec2.size)
local res = C.add(vec1.ptr, vec2.ptr, vecres.ptr, vec1.size, 64) -- right now assuming everything is 4 bytes
print ("My return code is " .. res)
C.writeOut(vecres.ptr, vecres.size)
end
A = mallocAsQTable(4000)
A.dataType = "int"
B = mallocAsQTable(4000)
B.dataType = "int"
C = mallocAsQTable(4000)
C.dataType = "int"
cfunc = addTwoVectors(A, B, C)
Out[1]:
Out[1]:
In [1]:
local run_gsl_test = function()
local ffi = require("ffi")
ffi.cdef [[typedef struct {
size_t size;
double * data;
} gsl_block;
typedef struct {
size_t size;
size_t stride;
double * data;
gsl_block * block;
int owner;
} gsl_vector;
typedef struct {
size_t size1;
size_t size2;
size_t tda;
double * data;
gsl_block * block;
int owner;
} gsl_matrix;
typedef struct {
gsl_vector vector;
} gsl_vector_view;
typedef struct {
gsl_matrix matrix;
} gsl_matrix_view;]]
ffi.cdef ( "gsl_vector* get_vector( int size );")
ffi.cdef ( "double * get_vector_pointer(gsl_vector* v);")
ffi.cdef ( "int print_array_data(double* arr, int size);")
ffi.cdef ( "int sum(double* arr, int size);")
ffi.cdef ( "int free_vector(gsl_vector * v);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libvec.so")
vector = C.get_vector(10)
darry = C.get_vector_pointer(vector)
darry = vector.data
C.print_array_data(darry, 10)
C.sum(darry, 10)
darry[10] = 10
darry[0] = 1
C.print_array_data(darry, 10)
C.free_vector(vector)
end
print ("hello")
run_gsl_test()
Out[1]:
Out[1]:
In [4]:
local run_gsl_test = function()
local ffi = require("ffi")
ffi.cdef [[typedef struct {
size_t size;
double * data;
} gsl_block;
typedef struct {
size_t size;
size_t stride;
double * data;
gsl_block * block;
int owner;
} gsl_vector;
typedef struct {
size_t size1;
size_t size2;
size_t tda;
double * data;
gsl_block * block;
int owner;
} gsl_matrix;
typedef struct {
gsl_vector vector;
} gsl_vector_view;
typedef struct {
gsl_matrix matrix;
} gsl_matrix_view;]]
ffi.cdef ( "gsl_vector* get_vector( int size );")
ffi.cdef ( "double * get_vector_pointer(gsl_vector* v);")
ffi.cdef ( "int print_array_data(double* arr, int size);")
ffi.cdef ( "int sum(double* arr, int size);")
ffi.cdef ( "int free_vector(gsl_vector * v);")
ffi.cdef ( "double* get_double_array(int size);")
ffi.cdef ( "int free_double_array(double* arr);")
ffi.cdef ( "gsl_vector_view make_vector(double* arr, int size);")
local C = ffi.load("/Users/indrajeetsingh/Dropbox/qtests/c_files/libvec.so")
darry = C.get_double_array(10)
vecview = C.make_vector(darry, 10)
vec = vecview.vector
if darry == vec.data then print ("Matches") else print ("Does not match") end
C.print_array_data(darry, 10)
C.sum(darry, 10)
darry[10] = 10
darry[0] = 1
C.print_array_data(darry, 10)
C.free_vector(vector)
C.free_double_array(darry)
end
print ("hello")
run_gsl_test()
Out[4]:
In [ ]: