Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding float buffer, Better Erlang API
- Loading branch information
Kevin Smith
committed
Mar 25, 2011
1 parent
27b518b
commit 61a6180
Showing
10 changed files
with
342 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#include <stdio.h> | ||
#include "pcuda_buffer.h" | ||
#include "pcuda_ops.h" | ||
|
||
PCudaFloatBuffer::PCudaFloatBuffer() { | ||
this->data = new std::vector<double>(); | ||
} | ||
|
||
PCudaFloatBuffer::~PCudaFloatBuffer() { | ||
delete this->data; | ||
} | ||
|
||
unsigned int PCudaFloatBuffer::size() { | ||
return this->data->size(); | ||
} | ||
|
||
void PCudaFloatBuffer::write(ErlNifEnv *env, ERL_NIF_TERM data) { | ||
ERL_NIF_TERM head; | ||
double value; | ||
|
||
while (enif_get_list_cell(env, data, &head, &data)) { | ||
if (enif_get_double(env, head, &value)) { | ||
this->data->push_back(value); | ||
} | ||
} | ||
} | ||
|
||
void PCudaFloatBuffer::delete_at(unsigned long position) { | ||
std::vector<double>::iterator iter = this->data->begin(); | ||
for (unsigned long i = 0; i < position; i++) { | ||
iter++; | ||
} | ||
this->data->erase(iter); | ||
} | ||
|
||
bool PCudaFloatBuffer::insert_at(unsigned long position, ErlNifEnv *env, ERL_NIF_TERM rawValue) { | ||
double value; | ||
if (enif_get_double(env, rawValue, &value)) { | ||
std::vector<double>::iterator iter = this->data->begin(); | ||
for (unsigned long i = 0; i < position; i++) { | ||
iter++; | ||
} | ||
this->data->insert(iter, 1, value); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool PCudaFloatBuffer::sort() { | ||
return pcuda_float_sort(this->data); | ||
} | ||
|
||
bool PCudaFloatBuffer::contains(ErlNifEnv *env, ERL_NIF_TERM rawTarget) { | ||
double target; | ||
if (enif_get_double(env, rawTarget, &target)) { | ||
return pcuda_float_binary_search(this->data, target); | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
|
||
ERL_NIF_TERM PCudaFloatBuffer::toErlTerms(ErlNifEnv *env) { | ||
std::vector<double>::iterator iter; | ||
ERL_NIF_TERM retval = enif_make_list(env, 0); | ||
if (this->data->size() > 0) { | ||
for (iter = this->data->end(); iter != this->data->begin();) { | ||
--iter; | ||
retval = enif_make_list_cell(env, enif_make_double(env, *iter), retval); | ||
} | ||
} | ||
return retval; | ||
} | ||
|
||
void PCudaFloatBuffer::clear() { | ||
this->data->clear(); | ||
} | ||
|
||
bool PCudaFloatBuffer::copy(PCudaBuffer *src) { | ||
if (src->type() == BUF_TYPE_FLOAT) { | ||
PCudaFloatBuffer *source = (PCudaFloatBuffer *) src; | ||
std::vector<double>::iterator iter; | ||
for (iter = source->data->begin(); iter != source->data->end(); ++iter) { | ||
this->data->push_back(*iter); | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
ERL_NIF_TERM PCudaFloatBuffer::intersect(ErlNifEnv *env, PCudaBuffer *otherBuffer) { | ||
ERL_NIF_TERM retval = enif_make_list(env, 0); | ||
std::vector<double> intersection; | ||
if (otherBuffer->type() == BUF_TYPE_FLOAT) { | ||
PCudaFloatBuffer *other = (PCudaFloatBuffer *) otherBuffer; | ||
pcuda_float_intersection(this->data, other->data, &intersection); | ||
if (intersection.size() > 0) { | ||
for (std::vector<double>::iterator iter = intersection.end(); iter != intersection.begin();) { | ||
--iter; | ||
retval = enif_make_list_cell(env, enif_make_double(env, *iter), retval); | ||
} | ||
} | ||
} | ||
return retval; | ||
} | ||
|
||
ERL_NIF_TERM PCudaFloatBuffer::minmax(ErlNifEnv *env) { | ||
double minmax[2]; | ||
pcuda_float_minmax(this->data, &minmax[0]); | ||
return enif_make_tuple2(env, enif_make_long(env, minmax[0]), enif_make_long(env, minmax[1])); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
-module(pteracuda_buffer). | ||
|
||
-include("pteracuda_internals.hrl"). | ||
|
||
-export([new/1, | ||
destroy/1, | ||
size/1, | ||
write/2, | ||
read/1, | ||
duplicate/1, | ||
clear/1, | ||
sort/2, | ||
contains/3, | ||
intersection/3, | ||
minmax/2]). | ||
|
||
new(integer) -> | ||
{ok, Buf} = pteracuda_nifs:new_int_buffer(), | ||
{ok, #pc_buffer{type=integer, ref=Buf}}; | ||
new(float) -> | ||
{ok, Buf} = pteracuda_nifs:new_float_buffer(), | ||
{ok, #pc_buffer{type=float, ref=Buf}}; | ||
new(string) -> | ||
{ok, Buf} = pteracuda_nifs:new_string_buffer(), | ||
{ok, #pc_buffer{type=string, ref=Buf}}. | ||
|
||
destroy(#pc_buffer{ref=Ref}) -> | ||
pteracuda_nifs:destroy_buffer(Ref), | ||
ok. | ||
|
||
size(#pc_buffer{ref=Ref}) -> | ||
pteracuda_nifs:buffer_size(Ref). | ||
|
||
write(#pc_buffer{ref=Ref, type=Type}, Data) when Type =:= integer orelse | ||
Type =:= string orelse | ||
Type =:= float -> | ||
pteracuda_nifs:write_buffer(Ref, Data). | ||
|
||
read(#pc_buffer{ref=Ref}) -> | ||
pteracuda_nifs:read_buffer(Ref). | ||
|
||
duplicate(#pc_buffer{ref=Ref, type=Type}) when Type =:= integer orelse | ||
Type =:= string orelse | ||
Type =:= float -> | ||
{ok, OtherBuf} = new(Type), | ||
pteracuda_nifs:copy_buffer(Ref, OtherBuf#pc_buffer.ref), | ||
{ok, OtherBuf}. | ||
|
||
clear(#pc_buffer{ref=Ref}) -> | ||
pteracuda_nifs:clear_buffer(Ref). | ||
|
||
sort(#pc_context{ref=Ctx}, #pc_buffer{ref=Buf}) -> | ||
pteracuda_nifs:sort_buffer(Ctx, Buf). | ||
|
||
contains(#pc_context{ref=Ctx}, #pc_buffer{ref=Buf}, Value) -> | ||
pteracuda_nifs:buffer_contains(Ctx, Buf, Value). | ||
|
||
intersection(#pc_context{ref=Ctx}, #pc_buffer{ref=Buf1}, #pc_buffer{ref=Buf2}) -> | ||
pteracuda_nifs:buffer_intersection(Ctx, Buf1, Buf2). | ||
|
||
minmax(#pc_context{ref=Ctx}, #pc_buffer{ref=Buf}) -> | ||
pteracuda_nifs:buffer_minmax(Ctx, Buf). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
-module(pteracuda_context). | ||
|
||
-include("pteracuda_internals.hrl"). | ||
|
||
-export([new/0, | ||
new/1, | ||
destroy/1]). | ||
|
||
new() -> | ||
{ok, Ctx} = pteracuda_nifs:new_context(), | ||
{ok, #pc_context{ref=Ctx}}. | ||
|
||
new(Device) when is_integer(Device) -> | ||
{ok, Ctx} = pteracuda_nifs:new_context(Device), | ||
{ok, #pc_context{ref=Ctx}}. | ||
|
||
destroy(#pc_context{ref=Ctx}) -> | ||
pteracuda_nifs:destroy_context(Ctx). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
-module(pteracuda_demo). | ||
|
||
-compile([export_all, | ||
native]). | ||
|
||
start(N) -> | ||
{T1, T2, T3} = erlang:now(), | ||
random:seed(T1, T2, T3), | ||
io:format("Generating test data: ~p~n", [N]), | ||
D = [random:uniform(N) || _ <- lists:seq(1, N)], | ||
io:format("Measuring performance "), | ||
{Time1, _} = timer:tc(lists, sort, [D]), | ||
io:format("."), | ||
{ok, C} = pteracuda_context:new(), | ||
{ok, B} = pteracuda_buffer:new(integer), | ||
pteracuda_buffer:write(B, D), | ||
{Time2, _} = timer:tc(pteracuda_demo, pteracuda_sort, [C, B, D]), | ||
io:format(".~n"), | ||
io:format("Erlang: ~pms, CUDA: ~pms~n", [Time1 / 1000, Time2 / 1000]). | ||
|
||
pteracuda_sort(C, B, D) -> | ||
pteracuda_buffer:write(B, D), | ||
pteracuda_buffer:sort(C, B), | ||
pteracuda_buffer:read(B). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
-record(pc_buffer, {type, | ||
ref}). | ||
|
||
-record(pc_context, {ref}). |
Oops, something went wrong.