Skip to content

Commit

Permalink
Merge pull request #85 from dmitry741/dev/dmitrypa-sdl-err-memory-han…
Browse files Browse the repository at this point in the history
…dling

SDL: err-memory-handling
  • Loading branch information
dmitry741 authored Sep 25, 2019
2 parents 46a17ec + e25bd3c commit 31f6c5a
Show file tree
Hide file tree
Showing 34 changed files with 381 additions and 95 deletions.
27 changes: 20 additions & 7 deletions algorithms/kernel/assocrules/assoc_rules_apriori_discover_impl.i
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void AssociationRulesKernel<apriori, algorithmFPType, cpu>::setIntersection(cons
*
*/
template<typename algorithmFPType, CpuType cpu>
void AssociationRulesKernel<apriori, algorithmFPType, cpu>::firstPass(
services::Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::firstPass(
double minConfidence, ItemSetList<cpu> *L, size_t itemSetSize,
const size_t *items, size_t itemsSupport,
size_t *leftItems, AssocRule<cpu> *R, size_t& numRules,
Expand All @@ -128,7 +128,13 @@ void AssociationRulesKernel<apriori, algorithmFPType, cpu>::firstPass(
for (size_t j = i + 1; j <= itemSetSize; ++j) { leftItems[j - 1] = items[j]; }

const assocrules_itemset<cpu> *left_iset = findItemSet(itemSetSize, leftItems, L_prev);
DAAL_CHECK(left_iset, services::ErrorNullInput);
DAAL_CHECK_STATUS_OK(left_iset->ok(), left_iset->getLastStatus());

const assocrules_itemset<cpu> *right_iset = findItemSet(1, &items[i], L_0);
DAAL_CHECK(right_iset, services::ErrorNullInput);
DAAL_CHECK_STATUS_OK(right_iset->ok(), right_iset->getLastStatus());

double confidence = (double)itemsSupport / (double)(left_iset->support.get());
if (confidence >= minConfidence)
{
Expand All @@ -138,6 +144,7 @@ void AssociationRulesKernel<apriori, algorithmFPType, cpu>::firstPass(
}
}
numRulesFound = numRules - oldNumRules;
return services::Status();
}

/**
Expand All @@ -158,7 +165,7 @@ void AssociationRulesKernel<apriori, algorithmFPType, cpu>::firstPass(
*
*/
template<typename algorithmFPType, CpuType cpu>
void AssociationRulesKernel<apriori, algorithmFPType, cpu>::nextPass(double minConfidence, ItemSetList<cpu> *L,
services::Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::nextPass(double minConfidence, ItemSetList<cpu> *L,
size_t right_size, size_t itemsSupport, size_t *leftItems, AssocRule<cpu> *R,
size_t& numRules, size_t& numLeft, size_t& numRight, size_t& numRulesFound,
bool& found)
Expand Down Expand Up @@ -189,6 +196,8 @@ void AssociationRulesKernel<apriori, algorithmFPType, cpu>::nextPass(double minC
}

assocrules_itemset<cpu> iset(right_size, first_items, second_items[right_size - 2]);
DAAL_CHECK_STATUS_OK(iset.ok(), iset.getLastStatus());

const assocrules_itemset<cpu> *right_iset = findItemSet(right_size, iset.items, L[right_size - 1]);
first_items = R[firstIdx ].left->items;
second_items = R[secondIdx].left->items;
Expand All @@ -211,6 +220,7 @@ void AssociationRulesKernel<apriori, algorithmFPType, cpu>::nextPass(double minC
}
}
numRulesFound = numRules - oldNumRules;
return services::Status();
}

/**
Expand All @@ -227,7 +237,7 @@ void AssociationRulesKernel<apriori, algorithmFPType, cpu>::nextPass(double minC
*
*/
template<typename algorithmFPType, CpuType cpu>
bool AssociationRulesKernel<apriori, algorithmFPType, cpu>::generateRules(double minConfidence, size_t minItemsetSize,
services::Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::generateRules(double minConfidence, size_t minItemsetSize,
size_t L_size, ItemSetList<cpu> *L,
AssocRule<cpu> *R, size_t& numRules, size_t& numLeft, size_t& numRight)
{
Expand All @@ -238,7 +248,7 @@ bool AssociationRulesKernel<apriori, algorithmFPType, cpu>::generateRules(double
TArray<size_t, cpu> leftItemsAr(L_size);
size_t *leftItems = leftItemsAr.get();
if(!leftItems)
return false;
return services::ErrorMemoryAllocationFailed;

/* Generate all association rules */
size_t startItemsetSize = 1;
Expand All @@ -254,19 +264,22 @@ bool AssociationRulesKernel<apriori, algorithmFPType, cpu>::generateRules(double
size_t n_rules_prev = 0;

/* Find rules that have 1 item in the right part */
firstPass(minConfidence, L, iset_size, items, itemsSupport,
services::Status statFirstPass = firstPass(minConfidence, L, iset_size, items, itemsSupport,
leftItems, R, numRules, numLeft, numRight, n_rules_prev);
DAAL_CHECK_STATUS_OK(statFirstPass.ok(), statFirstPass);

bool found = (n_rules_prev > 0);
for (size_t right_size = 2; right_size <= iset_size && found; ++right_size)
{
/* Find rules that have right_size items in the right part */
nextPass(minConfidence, L, right_size, itemsSupport,
services::Status statNextPass = nextPass(minConfidence, L, right_size, itemsSupport,
leftItems, R, numRules, numLeft, numRight, n_rules_prev, found);

DAAL_CHECK_STATUS_OK(statNextPass.ok(), statNextPass);
}
}
}
return true;
return services::Status();
}

template<typename algorithmFPType, CpuType cpu>
Expand Down
23 changes: 14 additions & 9 deletions algorithms/kernel/assocrules/assoc_rules_apriori_impl.i
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::compute(const Nume

/* Create association rules data set from input numeric table */
assocrules_dataset<cpu> data(dataTable, parameter->nTransactions, parameter->nUniqueItems, minSupport);
DAAL_CHECK_STATUS_OK(data.ok(), data.getLastStatus());

TArray<ItemSetList<cpu>, cpu> L(data.numOfUniqueItems);
DAAL_CHECK(L.get(), ErrorMemoryAllocationFailed);
Expand All @@ -67,8 +68,10 @@ Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::compute(const Nume
/* Find "large" itemsets */
size_t L_size = 0;
size_t maxItemsetSize = ((parameter->maxItemsetSize == 0) ? (size_t) - 1 : parameter->maxItemsetSize);
DAAL_CHECK(findLargeItemsets((size_t)daal::internal::Math<double, cpu>::sCeil(minSupport * data.numOfTransactions),
maxItemsetSize, data, L.get(), L_size), ErrorAprioriIncorrectInputData);
services::Status statLargeItemset = findLargeItemsets((size_t)daal::internal::Math<double,
cpu>::sCeil(minSupport * data.numOfTransactions),
maxItemsetSize, data, L.get(), L_size);
DAAL_CHECK_STATUS_OK(statLargeItemset.ok(), statLargeItemset);
DAAL_ASSERT(L_size > 0);

/* Allocate memory to store "large" itemsets */
Expand Down Expand Up @@ -99,7 +102,8 @@ Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::compute(const Nume
size_t nLeft = 0; /*<! Number of items in left parts of the rules */
size_t nRight = 0; /*<! Number of items in right parts of the rules */
double minConfidence = parameter->minConfidence;
DAAL_CHECK(generateRules(minConfidence, minItemsetSize, L_size, L.get(), R.get(), nRules, nLeft, nRight) && !!nRules, ErrorMemoryAllocationFailed);
services::Status statGenRules = generateRules(minConfidence, minItemsetSize, L_size, L.get(), R.get(), nRules, nLeft, nRight);
DAAL_CHECK_STATUS_OK(statGenRules.ok() && !!nRules, statGenRules);

NumericTable *leftItemsTable = r[2];
NumericTable *rightItemsTable = r[3];
Expand All @@ -115,14 +119,14 @@ Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::compute(const Nume
}

template <typename algorithmFPType, CpuType cpu>
bool AssociationRulesKernel<apriori, algorithmFPType, cpu>::findLargeItemsets(size_t minSupport, size_t maxItemsetSize,
services::Status AssociationRulesKernel<apriori, algorithmFPType, cpu>::findLargeItemsets(size_t minSupport, size_t maxItemsetSize,
assocrules_dataset<cpu> &data,
ItemSetList<cpu> *L, size_t& L_size)
{
/* Form list of "large" item sets of size 1 from the unique items
which count is not less than minimum count 'imin_s' */
if(!firstPass(minSupport, data, *L))
return false;
services::Status statFirstPass = firstPass(minSupport, data, *L);
DAAL_CHECK_STATUS_OK(statFirstPass.ok(), statFirstPass);

L_size = 1;
/* Find "large" item sets of size k+1 from itemsets of size k */
Expand All @@ -131,13 +135,14 @@ bool AssociationRulesKernel<apriori, algorithmFPType, cpu>::findLargeItemsets(si
hash_tree<cpu> *C_tree = NULL;
do
{
C_tree = nextPass(minSupport, k++, data, L, L_size, bFound, C_tree);
services::Status s;
C_tree = nextPass(minSupport, k++, data, L, L_size, bFound, C_tree, s);
DAAL_CHECK_STATUS_OK(s.ok(), s);
}
while(bFound && k < maxItemsetSize);

delete C_tree;
C_tree = nullptr;
return L_size > 0;
return (L_size > 0) ? services::Status() : services::ErrorAprioriIncorrectInputData;
}

template <typename algorithmFPType, CpuType cpu>
Expand Down
15 changes: 14 additions & 1 deletion algorithms/kernel/assocrules/assoc_rules_apriori_itemset.i
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,24 @@ struct assocrules_itemset
size_t *items; /*<! Array of items */
size_t size; /*<! Itemset size */

bool ok() const { return _status.ok(); }
services::Status getLastStatus() const { return _status; }

protected:
services::Status _status;

void allocItems(size_t n)
{
items = (size_t*)daal::services::daal_malloc(sizeof(size_t)*n);
size = n;
if (items)
{
_status = services::Status();
size = n;
}
else
{
_status = services::ErrorMemoryAllocationFailed;
}
}
};

Expand Down
16 changes: 8 additions & 8 deletions algorithms/kernel/assocrules/assoc_rules_apriori_kernel.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class AssociationRulesKernel<apriori, algorithmFPType, cpu> : public Kernel
/** Find "large" item sets and build association rules */
services::Status compute(const NumericTable *a, NumericTable *r[], const daal::algorithms::Parameter *parameter);
protected:
bool findLargeItemsets(size_t minSupport, size_t maxItemsetSize, assocrules_dataset<cpu> &data, ItemSetList<cpu> *L, size_t& L_size);
services::Status findLargeItemsets(size_t minSupport, size_t maxItemsetSize, assocrules_dataset<cpu> &data, ItemSetList<cpu> *L, size_t& L_size);

Status allocateItemsetsTableData(ItemSetList<cpu> *L, size_t L_size, size_t minItemsetSize,
NumericTable *largeItemsetsTable, NumericTable *largeItemsetsSupportTable,
Expand All @@ -68,23 +68,23 @@ class AssociationRulesKernel<apriori, algorithmFPType, cpu> : public Kernel
*/

/** Find "large" itemsets of size 1 */
bool firstPass(size_t imin_s, assocrules_dataset<cpu> &data, ItemSetList<cpu>& l);
services::Status firstPass(size_t imin_s, assocrules_dataset<cpu> &data, ItemSetList<cpu>& l);

/** Generate "large" item sets of size k+1 from "large" item sets of size k */
hash_tree<cpu> * nextPass(size_t imin_s, size_t iset_size, assocrules_dataset<cpu> &data, ItemSetList<cpu> *L, size_t& L_size,
bool& bFound, hash_tree<cpu> *C_tree);
bool& bFound, hash_tree<cpu> *C_tree, services::Status& s);

/** Test that all {n-1}-item subsets of {n}-item set are "large" item sets */
bool pruneCandidate(size_t iset_size, const size_t *cadidate, size_t *subset, hash_tree<cpu> &C_tree);

size_t binarySearch(size_t nUniqueItems, assocRulesUniqueItem<cpu> *uniqueItems, size_t itemID);

assocrules_itemset<cpu> * genCandidate(size_t iset_size, size_t *first_items, size_t second_item,
size_t *subset_buf, hash_tree<cpu> *C_tree);
size_t *subset_buf, hash_tree<cpu> *C_tree, services::Status& s);

/** Generate candidate itemsets of size iset_size+1 from "large" itemsets of size iset_size */
bool genCandidates(size_t iset_size, ItemSetList<cpu> *L, hash_tree<cpu> *C_tree,
size_t nUniqueItems, assocRulesUniqueItem<cpu> *uniqueItems);
size_t nUniqueItems, assocRulesUniqueItem<cpu> *uniqueItems, services::Status& s);

/** Generate all subsets of size iset_size from a transaction and hash those subsets
using hash tree of candidate itemsets C_tree to increment support values of candidates */
Expand All @@ -106,18 +106,18 @@ class AssociationRulesKernel<apriori, algorithmFPType, cpu> : public Kernel
void setIntersection(const size_t *a, size_t aSize, const size_t *b, size_t bSize, size_t *c, size_t& cSize);

/** Find rules containing 1 item on the right */
void firstPass(double minConfidence, ItemSetList<cpu> *L, size_t itemSetSize, const size_t *items, size_t itemsSupport,
services::Status firstPass(double minConfidence, ItemSetList<cpu> *L, size_t itemSetSize, const size_t *items, size_t itemsSupport,
size_t *leftItems, AssocRule<cpu> *R, size_t& numRules,
size_t& numLeft, size_t& numRight, size_t& numRulesFound);

/** Generate rules that have k+1 items on the right from the rules that have k items on the right */
void nextPass(double minConfidence, ItemSetList<cpu> *L, size_t right_size,
services::Status nextPass(double minConfidence, ItemSetList<cpu> *L, size_t right_size,
size_t itemsSupport, size_t *leftItems, AssocRule<cpu> *R,
size_t& numRules, size_t& numLeft, size_t& numRight, size_t& numRulesFound,
bool& found);

/** Generate association rules from "large" item sets */
bool generateRules(double minConfidence, size_t minItemsetSize, size_t L_size, ItemSetList<cpu> *L,
services::Status generateRules(double minConfidence, size_t minItemsetSize, size_t L_size, ItemSetList<cpu> *L,
AssocRule<cpu> *R, size_t& numRules, size_t& numLeft, size_t& numRight);

/** Store association rules into continuous memory */
Expand Down
Loading

0 comments on commit 31f6c5a

Please sign in to comment.