Skip to content

Commit

Permalink
bxx: Fixed random-number generators and anon-slicing.
Browse files Browse the repository at this point in the history
  • Loading branch information
safl committed May 27, 2015
1 parent e50762e commit 825034f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 31 deletions.
11 changes: 11 additions & 0 deletions bridge/cpp/bxx/bohrium.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ int64_t unpack_shape(int64_t *shape, size_t index, size_t arg, Args... args)
return 1;
}

inline int64_t nelements_shape(size_t arg)
{
return arg;
}

template <typename ...Args>
int64_t nelements_shape(size_t arg, Args... args)
{
return arg*nelements_shape(args...);
}

//
// Extensions
//
Expand Down
33 changes: 15 additions & 18 deletions bridge/cpp/bxx/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BOHRIUM_BRIDGE_CPP_GENERATOR
#define __BOHRIUM_BRIDGE_CPP_GENERATOR
#include <limits>

namespace bxx {

Expand Down Expand Up @@ -74,38 +75,34 @@ multi_array<T>& zeros(const Dimensions&... shape)

//
// Sugar

template <typename T, typename ...Dimensions>
multi_array<T>& random(const Dimensions&... shape)
{
// Generate some random numbers
multi_array<uint64_t>* rand_result = new multi_array<uint64_t>(shape...);
rand_result->setTemp(true);
int64_t nelements = nelements_shape(shape...);
// Generate numbers
multi_array<uint64_t>* rand_result = new multi_array<uint64_t>(nelements);
rand_result->link();

bh_random(*rand_result, (uint64_t)0, (uint64_t)time(NULL));

// Convert them to the requested type
multi_array<T>* result = new multi_array<T>(shape...);
result->setTemp(true);
rand_result->setTemp(true);

multi_array<T>* result = new multi_array<T>(nelements); // Convert their type
result->link();

bh_identity(*result, *rand_result);
result->setTemp(true);

// Return them to the user
return *result;
return view_as(*result, shape...); // Reshape them
}

template <typename T, typename ...Dimensions>
multi_array<T>& randu(const Dimensions&... shape)
{
multi_array<uint64_t>* rand_result = &random<uint64_t>(shape...);

multi_array<T>* result = new multi_array<T>(shape...);
result->link();

bh_identity(*result, *rand_result);
bh_divide(*result, *result, (T)sizeof(T));
multi_array<T>* result = &random<T>(shape...); // Generate numbers

result->setTemp(false); // Map them to [0,1]
bh_divide(*result,
*result,
(T)std::numeric_limits<uint64_t>::max());
result->setTemp(true);

return *result;
Expand Down
34 changes: 21 additions & 13 deletions bridge/cpp/bxx/multi_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,25 +520,33 @@ template <typename T>
multi_array<T>& multi_array<T>::operator=(multi_array<T>& rhs)
{
if ((linked()) && (meta.base == rhs.getBase())) { // Self-aliasing is a NOOP
//std::cout << "Self-aliasing..." << std::endl;
return *this;
}

if (linked()) {
Runtime::instance().ref_count[meta.base] -= 1; // Decrement ref-count
if (0==Runtime::instance().ref_count[meta.base]) { // De-allocate it
bh_free(*this); // Send BH_FREE to Bohrium
bh_discard(*this); // Send BH_DISCARD to Bohrium
Runtime::instance().trash(meta.base); // Queue the bh_base for de-allocation
Runtime::instance().ref_count.erase(meta.base); // Remove from ref-count
if (getTemp()) { // Assign to view
bh_identity(*this, rhs);
} else { // Aliasing
//std::cout << "Aliasing..." << std::endl;
if (linked()) {
//std::cout << "Unlinking..." << std::endl;
Runtime::instance().ref_count[meta.base] -= 1; // Decrement ref-count
if (0==Runtime::instance().ref_count[meta.base]) { // De-allocate it
bh_free(*this); // Send BH_FREE to Bohrium
bh_discard(*this); // Send BH_DISCARD to Bohrium
Runtime::instance().trash(meta.base); // Queue the bh_base for de-allocation
Runtime::instance().ref_count.erase(meta.base); // Remove from ref-count
}
unlink();
}
unlink();
}

meta = rhs.meta; // Create the alias
Runtime::instance().ref_count[meta.base] +=1;
meta = rhs.meta; // Create the alias
Runtime::instance().ref_count[meta.base] +=1;

if (rhs.getTemp()) { // Delete temps
delete &rhs; // The deletion will decrement the ref-count
if (rhs.getTemp()) { // Delete temps
//std::cout << "Deleting RHS" << std::endl;
delete &rhs; // The deletion will decrement the ref-count
}
}

return *this;
Expand Down

0 comments on commit 825034f

Please sign in to comment.