virtual NDArray GetLabel(void) { const int* indices = random->data(); mx_float *label = new mx_float[sequence_length * batch], *plabel = label; for (int i = current * batch, end = i + batch; i < end; i++) { memcpy(plabel, sequences[indices[i]].data() + 1, (sequences[indices[i]].size() - 1) * sizeof(mx_float)); memset(plabel + sequences[indices[i]].size() - 1, 0, (sequence_length - sequences[indices[i]].size() + 1) * sizeof(mx_float)); plabel += sequence_length; } NDArray array(Shape(batch, sequence_length), device, false); array.SyncCopyFromCPU(label, batch * sequence_length); return array; }
virtual NDArray GetData(void) { const int* indices = random->data(); mx_float *data = new mx_float[sequence_length * batch], *pdata = data; for (int i = current * batch, end = i + batch; i < end; i++) { memcpy(pdata, sequences[indices[i]].data(), sequences[indices[i]].size() * sizeof(mx_float)); if (sequences[indices[i]].size() < sequence_length) memset(pdata + sequences[indices[i]].size(), 0, (sequence_length - sequences[indices[i]].size()) * sizeof(mx_float)); pdata += sequence_length; } NDArray array(Shape(batch, sequence_length), device, false); array.SyncCopyFromCPU(data, batch * sequence_length); return array; }
virtual void BeforeFirst(void) { current = -1; random->shuffle(nullptr); }
virtual std::vector<int> GetIndex(void) { const int* indices = random->data(); vector<int> list(indices + current * batch, indices + current * batch + batch); return list; }
virtual int GetPadNum(void) { return sequence_length - sequences[random->data()[current * batch]].size(); }
/** * \fn int main() * * \brief Executes the mergesort() and the quicksort() algorithms on * several arrays of varying size, and then computes the average * execution time of each method on each array of the same size. The * size of each array is always a power of 2, varying from 8 to * 2^20. The average execution times are written out to the standard * output. * * \return The status of the function termination. * * ------------------------------------------------------------------- * * You should run this code with the following command-line: * * ./mainapp * * or * * ./mainapp > output filename * * ------------------------------------------------------------------- */ int main() { /* * Usage: ./mainapp [ > output filename ] */ /* * Instantiate the mergesort and quicksort objects. */ MySort* ms_sorter = new MergeSort() ; MySort* qs_sorter = new QuickSort() ; /* * Instantiate the array "shuffler". */ Shuffler shuffler ; /* * Set up the format for displaying the output numbers. */ cout << std::scientific << std::setprecision( 16 ) ; /* * Set up the execution params */ int begin_power = 3; int end_power = 20; int times_sorting = 5; /* * Run the method for arrays of size 2^i */ cerr << "Executing the sorting method on " << end_power - begin_power + 1 << " distinctly-sized arrays (" << times_sorting << ") times for each)..." << endl ; cerr << endl ; cerr << "This may take some time... Get a coffee or play a game!" << endl ; cerr << endl ; int n = 2; n <<= begin_power-1; for ( int i = begin_power ; i <= end_power ; i++ ) { cerr << endl ; cerr << "-----------------------------------------------------" << endl ; cerr << "Allocating memory for an array of size " << n << " (2^" << i << ")" << "..." << endl ; /* * Allocate memory for two arrays of n integers each. */ int* a = new int[ n ] ; int* b = new int[ n ] ; cerr << "Filling in the array with integers from 1 to " << n << "..." << endl ; /* * Fill out the array with the integers from 1 to n. */ for ( int i = 0 ; i < n ; i++ ) { a[ i ] = i + 1 ; } /* * Execute the method some times, each of which takes in a possibly * distinct permutation of the array. This is not ideal, as the * number of permutations of the arrays grows exponentially as we * double the size of the array. However, if we try to be "fair" * (say, by executing the method a number of times equal to 1% of * the number of permutations), this application will take forever * to run. So, just keep in mind that the average time is less * representative as the size of the array grows (this is not * ideal). */ cerr << "Shuffling and sorting the array " << times_sorting << " times..." << endl ; double mstime = 0 ; double qstime = 0 ; for ( int j = 0 ; j < times_sorting ; j++ ) { /* * Shuffle the array (again). In principle, any permutation of * the array is equally likely to be produced by the method * shuffle(). */ shuffler.shuffle( &a[ 0 ] , n ) ; /* * Make a copy of array "a". */ for ( int i = 0 ; i < n ; i++ ) { b[ i ] = a[ i ] ; } /* * Sort the array in non-decreasing order and record the time * (in milliseconds) that the mergesort algorithm took to sort * the array. */ clock_t start , end ; start = clock() ; ms_sorter->sort( a , n ) ; end = clock() ; /* * Compute the cpu time of the execution. */ mstime += double( end - start ) ; /* * Check if the sorting method correctly sorted the array. If it * did, then write out the size of the array and the execution * time. Otherwise, write out an error message and abort the * execution. */ for ( int j = 1 ; j < n ; j++ ) { if ( a[ j ] < a[ j - 1 ] ) { cerr << "Your implementation of the mergesort algorithm is incorrect!" << endl ; return EXIT_FAILURE ; } } /* * Sort the array in non-decreasing order and record the time * (in milliseconds) that the quick sort algorithm took to sort * the array. */ start = clock() ; qs_sorter->sort( b , n ) ; end = clock() ; /* * Compute the cpu time of the execution. */ qstime += double( end - start ) ; /* * Check if the sorting method correctly sorted the array. If it * did, then write out the size of the array and the execution * time. Otherwise, write out an error message and abort the * execution. */ for ( int j = 1 ; j < n ; j++ ) { if ( b[ j ] < b[ j - 1 ] ) { cerr << "Your implementation of the quicksort algorithm is incorrect!" << endl ; return EXIT_FAILURE ; } } cerr << "Done sorting for array with " << n << " elements " << "the " << j+1 << "th time" << endl ; } /* * Write out array size and the average execution size. */ cout << n << '\t' << std::setw( 24 ) << mstime / ( 100 * CLOCKS_PER_SEC ) << '\t' << std::setw( 24 ) << qstime / ( 100 * CLOCKS_PER_SEC ) << endl ; /* * Double the size of the array. */ n <<= 1 ; /* * Release the memory allocated for the arrays "a" and "b". */ if ( a != 0 ) { delete a ; } if ( b != 0 ) { delete b ; } cerr << "-----------------------------------------------------" << endl ; } /* * Release the memory allocated for the sorting method objects. */ if ( ms_sorter != 0 ) { delete ms_sorter ; } if ( qs_sorter != 0 ) { delete qs_sorter ; } cerr << endl << endl ; return EXIT_SUCCESS ; }
/** * \fn int main( int argc , char* argv[] ) * * \brief Executes the insertion sort algorithm and the merge sort * algorithm on several permutations of an array consisting of the * integers 1 thru N, where N is a given positive integer. You can use * this application to estimate the average execution time of both * merge sort and insertion sort for "small" arrays. The idea is to * estimate the largest value of N for which the average time taken by * the insertion sort algorithm is smaller than the average time taken * by the merge sort algorithm to sort some permutations of a given * array of fixed size. Once you know N, you can change the code of * the merge sort algorithm, so that it calls the insertion sort * algorithm whenever the size of the subarray gets equal to or * smaller than N. * * You should run this code with the following command-line: * * ./mainapp N * * \param argc The number of command line arguments. * \param argv The command line arguments. * * \return The status of the function termination. */ int main( int argc, char* argv[] ) { using std::cout ; using std::cerr ; using std::endl ; /* * Check the number of input parameters. */ if ( argc != 2 ) { cerr << "Usage: ./mainapp N" << endl ; return EXIT_FAILURE ; } /* * Get the size of the array to be sorted. */ int n = atoi( argv[ 1 ] ) ; assert( n > 0 ) ; /* * Instantiate the insertion sort and merge sort objects. */ MySort* is_sorter = new InsertionSort() ; MySort* ms_sorter = new MergeSort() ; /* * Instantiate the array "shuffler". */ Shuffler shuffler ; /* * Set up the format for displaying the output numbers. */ cout << std::scientific << std::setprecision( 16 ) ; /* * Set up the execution params */ int times_sorting = 100; /* * Run the method for 100 permutations of an arrays of size n. */ cerr << "Executing the sorting method on " << n << "distinctly-sized arrays (" << times_sorting << ") times for each)..." << endl ; cerr << "Allocating memory for an array of size " << n << "..." << endl ; /* * Allocate memory for two arrays of n integers each. */ int* a = new int[ n ] ; int* b = new int[ n ] ; cerr << "Filling in the array with integers from 1 to " << n << "..." << endl ; /* * Fill out the array with the integers from 1 to n. */ for ( int i = 0 ; i < n ; i++ ) { a[ i ] = i + 1 ; } /* * Execute the method 100 times, each of which takes in a possibly * distinct permutation of the array. */ cerr << "Shuffling and sorting the array " << times_sorting << " times..." << endl ; double istime = 0 ; double mstime = 0 ; for ( int j = 0 ; j < times_sorting ; j++ ) { /* * Shuffle the array (again). In principle, any permutation of the * array is equally likely to be produced by the method shuffle(). */ shuffler.shuffle( &a[ 0 ] , n ) ; /* * Make a copy of array "a". */ for ( int i = 0 ; i < n ; i++ ) { b[ i ] = a[ i ] ; } /* * Sort the array in non-decreasing order and record the time (in * milliseconds) that the insertion sort algorithm took to sort * the array. */ clock_t start , end ; start = clock() ; is_sorter->sort( a , n ) ; end = clock() ; /* * Compute the cpu time of the execution. */ istime += double( end - start ) ; /* * Check if the sorting method correctly sorted the array. If it * did, then write out the size of the array and the execution * time. Otherwise, write out an error message and abort the * execution. */ for ( int j = 1 ; j < n ; j++ ) { if ( a[ j ] < a[ j - 1 ] ) { cerr << "Your implementation of the insertion sort algorithm is incorrect!" << endl ; return EXIT_FAILURE ; } } /* * Sort the array in non-decreasing order and record the time (in * milliseconds) that the merge sort algorithm took to sort the * array. */ start = clock() ; ms_sorter->sort( b , n ) ; end = clock() ; /* * Compute the cpu time of the execution. */ mstime += double( end - start ) ; /* * Check if the sorting method correctly sorted the array. If it * did, then write out the size of the array and the execution * time. Otherwise, write out an error message and abort the * execution. */ for ( int j = 1 ; j < n ; j++ ) { if ( b[ j ] < b[ j - 1 ] ) { cerr << "Your implementation of the merge sort algorithm is incorrect!" << endl ; return EXIT_FAILURE ; } } cerr << "Done sorting for array with " << n << " elements " << "the " << j+1 << "th time" << endl ; } /* * Write the average execution time of each method. */ cout << "INSERTION SORT: " << std::setw( 24 ) << istime / ( 100 * CLOCKS_PER_SEC ) << endl << " MERGE SORT: " << std::setw( 24 ) << mstime / ( 100 * CLOCKS_PER_SEC ) << endl ; /* * Release the memory allocated for the arrays. */ if ( a != 0 ) { delete a ; } if ( b != 0 ) { delete b ; } /* * Release the memory allocated for the sorting method object. */ if ( is_sorter != 0 ) { delete is_sorter ; } if ( ms_sorter != 0 ) { delete ms_sorter ; } cerr << endl << endl ; return EXIT_SUCCESS ; }