LCOV - code coverage report
Current view: top level - monetdb5/modules/kernel - microbenchmark.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 199 0.0 %
Date: 2021-10-13 02:24:04 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * @a stefan manegold
      11             :  * @+
      12             :  * The microbenchmark routines are primarilly used to create a
      13             :  * simple database for testing the performance of core routines.
      14             :  * It was originally developed in the context of the Radix Cluster
      15             :  * activities.
      16             :  * @f microbenchmark
      17             :  */
      18             : #include "monetdb_config.h"
      19             : #include "mal.h"
      20             : #include "mal_exception.h"
      21             : #include "mal.h"
      22             : 
      23             : #ifndef WIN32
      24             : #define __declspec(x)
      25             : #endif
      26             : 
      27             : extern __declspec(dllexport) str MBMrandom(bat *ret, oid *base, lng *size, int *domain);
      28             : extern __declspec(dllexport) str MBMrandom_seed(bat *ret, oid *base, lng *size, int *domain, const int *seed);
      29             : extern __declspec(dllexport) str MBMuniform(bat *ret, oid *base, lng *size, int *domain);
      30             : extern __declspec(dllexport) str MBMnormal(bat *ret, oid *base, lng *size, int *domain, int *stddev, int *mean);
      31             : extern __declspec(dllexport) str MBMmix(bat *ret, bat *batid);
      32             : extern __declspec(dllexport) str MBMskewed(bat *ret, oid *base, lng *size, int *domain, int *skew);
      33             : 
      34             : static gdk_return
      35           0 : BATrandom(BAT **bn, oid *base, lng *size, int *domain, int seed)
      36             : {
      37           0 :         const BUN n = (BUN) * size;
      38             :         BUN i;
      39             :         BAT *b = NULL;
      40             :         int *restrict val;
      41             : 
      42           0 :         if (*size > (lng)BUN_MAX) {
      43           0 :                 GDKerror("size must not exceed BUN_MAX");
      44           0 :                 return GDK_FAIL;
      45             :         }
      46             : 
      47           0 :         if (*size < 0) {
      48           0 :                 GDKerror("size must not be negative");
      49           0 :                 return GDK_FAIL;
      50             :         }
      51             : 
      52           0 :         b = COLnew(*base, TYPE_int, n, TRANSIENT);
      53           0 :         if (b == NULL)
      54             :                 return GDK_FAIL;
      55           0 :         if (n == 0) {
      56           0 :                 b->tsorted = true;
      57           0 :                 b->trevsorted = false;
      58           0 :                 b->tseqbase = oid_nil;
      59           0 :                 BATkey(b, true);
      60           0 :                 *bn = b;
      61           0 :                 return GDK_SUCCEED;
      62             :         }
      63           0 :         val = (int *) Tloc(b, 0);
      64             : 
      65             :         /* create BUNs with random distribution */
      66           0 :         if (!is_int_nil(seed))
      67           0 :                 srand(seed);
      68           0 :         if (is_int_nil(*domain)) {
      69           0 :                 for (i = 0; i < n; i++) {
      70           0 :                         val[i] = rand();
      71             :                 }
      72             : #if RAND_MAX < 46340     /* 46340*46340 = 2147395600 < INT_MAX */
      73             :         } else if (*domain > RAND_MAX + 1) {
      74             :                 for (i = 0; i < n; i++) {
      75             :                         val[i] = (rand() * (RAND_MAX + 1) + rand()) % *domain;
      76             :                 }
      77             : #endif
      78             :         } else {
      79           0 :                 for (i = 0; i < n; i++) {
      80           0 :                         val[i] = rand() % *domain;
      81             :                 }
      82             :         }
      83             : 
      84           0 :         BATsetcount(b, n);
      85           0 :         b->tsorted = false;
      86           0 :         b->trevsorted = false;
      87           0 :         b->tseqbase = oid_nil;
      88           0 :         BATkey(b, false);
      89           0 :         *bn = b;
      90           0 :         return GDK_SUCCEED;
      91             : }
      92             : 
      93             : static gdk_return
      94           0 : BATuniform(BAT **bn, oid *base, lng *size, int *domain)
      95             : {
      96           0 :         const BUN n = (BUN) * size;
      97             :         BUN i, r;
      98             :         BAT *b = NULL;
      99             :         int *restrict val;
     100             :         int v;
     101             : 
     102           0 :         if (*size > (lng)BUN_MAX) {
     103           0 :                 GDKerror("size must not exceed BUN_MAX");
     104           0 :                 return GDK_FAIL;
     105             :         }
     106             : 
     107           0 :         if (*size < 0) {
     108           0 :                 GDKerror("size must not be negative");
     109           0 :                 return GDK_FAIL;
     110             :         }
     111             : 
     112           0 :         b = COLnew(*base, TYPE_int, n, TRANSIENT);
     113           0 :         if (b == NULL)
     114             :                 return GDK_FAIL;
     115           0 :         if (n == 0) {
     116           0 :                 b->tsorted = true;
     117           0 :                 b->trevsorted = false;
     118           0 :                 b->tseqbase = oid_nil;
     119           0 :                 BATkey(b, true);
     120           0 :                 *bn = b;
     121           0 :                 return GDK_SUCCEED;
     122             :         }
     123           0 :         val = (int *) Tloc(b, 0);
     124             : 
     125             :         /* create BUNs with uniform distribution */
     126           0 :         for (v = 0, i = 0; i < n; i++) {
     127           0 :                 val[i] = v;
     128           0 :                 if (++v >= *domain)
     129             :                         v = 0;
     130             :         }
     131             : 
     132             :         /* mix BUNs randomly */
     133           0 :         for (r = 0, i = 0; i < n; i++) {
     134           0 :                 const BUN j = i + ((r += rand()) % (n - i));
     135           0 :                 const int tmp = val[i];
     136             : 
     137           0 :                 val[i] = val[j];
     138           0 :                 val[j] = tmp;
     139             :         }
     140             : 
     141           0 :         BATsetcount(b, n);
     142           0 :         b->tsorted = false;
     143           0 :         b->trevsorted = false;
     144           0 :         b->tseqbase = oid_nil;
     145           0 :         BATkey(b, *size <= *domain);
     146           0 :         *bn = b;
     147           0 :         return GDK_SUCCEED;
     148             : }
     149             : 
     150             : static gdk_return
     151           0 : BATskewed(BAT **bn, oid *base, lng *size, int *domain, int *skew)
     152             : {
     153           0 :         const BUN n = (BUN) * size;
     154             :         BUN i, r;
     155             :         BAT *b = NULL;
     156             :         int *restrict val;
     157           0 :         const BUN skewedSize = ((*skew) * n) / 100;
     158           0 :         const int skewedDomain = ((100 - (*skew)) * (*domain)) / 100;
     159             : 
     160           0 :         if (*size > (lng)BUN_MAX) {
     161           0 :                 GDKerror("size must not exceed BUN_MAX = " BUNFMT, BUN_MAX);
     162           0 :                 return GDK_FAIL;
     163             :         }
     164             : 
     165           0 :         if (*size < 0) {
     166           0 :                 GDKerror("size must not be negative");
     167           0 :                 return GDK_FAIL;
     168             :         }
     169             : 
     170           0 :         if (*skew > 100 || *skew < 0) {
     171           0 :                 GDKerror("skew must be between 0 and 100");
     172           0 :                 return GDK_FAIL;
     173             :         }
     174             : 
     175           0 :         b = COLnew(*base, TYPE_int, n, TRANSIENT);
     176           0 :         if (b == NULL)
     177             :                 return GDK_FAIL;
     178           0 :         if (n == 0) {
     179           0 :                 b->tsorted = true;
     180           0 :                 b->trevsorted = false;
     181           0 :                 b->tseqbase = oid_nil;
     182           0 :                 BATkey(b, true);
     183           0 :                 *bn = b;
     184           0 :                 return GDK_SUCCEED;
     185             :         }
     186           0 :         val = (int *) Tloc(b, 0);
     187             : 
     188             :         /* create BUNs with skewed distribution */
     189           0 :         for (i = 0; i < skewedSize; i++)
     190           0 :                 val[i] = rand() % skewedDomain;
     191           0 :         for( ; i < n; i++)
     192           0 :                 val[i] = (rand() % (*domain - skewedDomain)) + skewedDomain;
     193             : 
     194             :         /* mix BUNs randomly */
     195           0 :         for (r = 0, i = 0; i < n; i++) {
     196           0 :                 const BUN j = i + ((r += rand()) % (n - i));
     197           0 :                 const int tmp = val[i];
     198             : 
     199           0 :                 val[i] = val[j];
     200           0 :                 val[j] = tmp;
     201             :         }
     202             : 
     203           0 :         BATsetcount(b, n);
     204           0 :         b->tsorted = false;
     205           0 :         b->trevsorted = false;
     206           0 :         b->tseqbase = oid_nil;
     207           0 :         BATkey(b, *size <= *domain);
     208           0 :         *bn = b;
     209           0 :         return GDK_SUCCEED;
     210             : }
     211             : 
     212             : 
     213             : /* math.h files do not have M_PI/M_E defined */
     214             : #ifndef M_PI
     215             : # define M_PI           ((dbl) 3.14159265358979323846)  /* pi */
     216             : #endif
     217             : #ifndef M_E
     218             : # define M_E            ((dbl) 2.7182818284590452354)   /* e */
     219             : #endif
     220             : 
     221             : static gdk_return
     222           0 : BATnormal(BAT **bn, oid *base, lng *size, int *domain, int *stddev, int *mean)
     223             : {
     224           0 :         const BUN n = (BUN) * size;
     225             :         BUN i, r;
     226           0 :         const int d = (*domain < 0 ? 0 : *domain);
     227             :         int j;
     228             :         BAT *b = NULL;
     229             :         int *restrict val;
     230           0 :         const int m = *mean, s = *stddev;
     231             :         unsigned int *restrict abs;
     232             :         flt *restrict rel;
     233             :         dbl tot = 0;
     234           0 :         const dbl s_s_2 = (dbl) s * (dbl) s * 2;
     235           0 :         const dbl s_sqrt_2_pi = ((dbl) s * sqrt(2 * M_PI));
     236             : 
     237             :         assert(sizeof(unsigned int) == sizeof(flt));
     238             : 
     239             : #if SIZEOF_BUN > 4
     240           0 :         if (n >= ((ulng) 1 << 32)) {
     241           0 :                 GDKerror("size must be less than 2^32 = "LLFMT, (lng) 1 << 32);
     242           0 :                 return GDK_FAIL;
     243             :         }
     244             : #endif
     245             :         if (*size > (lng)BUN_MAX) {
     246             :                 GDKerror("size must not exceed BUN_MAX");
     247             :                 return GDK_FAIL;
     248             :         }
     249             : 
     250             :         if (*size < 0) {
     251             :                 GDKerror("size must not be negative");
     252             :                 return GDK_FAIL;
     253             :         }
     254             : 
     255           0 :         b = COLnew(*base, TYPE_int, n, TRANSIENT);
     256           0 :         if (b == NULL) {
     257             :                 return GDK_FAIL;
     258             :         }
     259           0 :         if (n == 0) {
     260           0 :                 b->tsorted = true;
     261           0 :                 b->trevsorted = false;
     262           0 :                 b->tseqbase = oid_nil;
     263           0 :                 BATkey(b, true);
     264           0 :                 *bn = b;
     265           0 :                 return GDK_SUCCEED;
     266             :         }
     267           0 :         val = (int *) Tloc(b, 0);
     268             : 
     269           0 :         abs = (unsigned int *) GDKmalloc(d * sizeof(unsigned int));
     270           0 :         if (abs == NULL) {
     271           0 :                 BBPreclaim(b);
     272           0 :                 return GDK_FAIL;
     273             :         }
     274             :         rel = (flt *) abs;
     275             : 
     276             :         /* assert(0 <= *mean && *mean < *size); */
     277             : 
     278             :         /* created inverted table with rel fraction per value */
     279           0 :         for (tot = 0, j = 0; j < d; j++) {
     280           0 :                 const dbl j_m = (dbl) j - m;
     281           0 :                 const dbl tmp = j_m * j_m / s_s_2;
     282             : 
     283           0 :                 rel[j] = (flt) (pow(M_E, -tmp) / s_sqrt_2_pi);
     284           0 :                 tot += rel[j];
     285             :         }
     286             :         /* just in case we get tot != 1 due to. e.g.,
     287             :          * rounding errors, limited precision, or limited domain */
     288           0 :         tot = 1.0 / tot;
     289             :         /* calculate abs count per value from rel fraction */
     290           0 :         for (r = n, j = 0; j < d; j++) {
     291           0 :                 assert(((dbl) n * rel[j] * tot) < (dbl) ((lng) 1 << 32));
     292           0 :                 abs[j] = (unsigned int) ((dbl) n * rel[j] * tot);
     293           0 :                 assert(r >= abs[j]);
     294           0 :                 r -= abs[j];
     295             :         }
     296           0 :         assert(((ulng) 1 << 32) - r > abs[m]);
     297           0 :         abs[m] += (unsigned int) r;
     298             : 
     299             :         /* create BUNs with normal distribution */
     300           0 :         for (j = 0, i = 0; i < n && j < d; i++) {
     301           0 :                 while (j < d && abs[j] == 0)
     302           0 :                         j++;
     303           0 :                 if (j < d) {
     304           0 :                         val[i] = j;
     305           0 :                         abs[j]--;
     306             :                 }
     307             :         }
     308           0 :         assert(i == n);
     309           0 :         while (j < d && abs[j] == 0)
     310           0 :                 j++;
     311           0 :         assert(j == d);
     312           0 :         GDKfree(abs);
     313             : 
     314             : 
     315           0 :         BATsetcount(b, n);
     316           0 :         b->tsorted = false;
     317           0 :         b->trevsorted = false;
     318           0 :         b->tseqbase = oid_nil;
     319           0 :         BATkey(b, n<2);
     320           0 :         *bn = b;
     321           0 :         return GDK_SUCCEED;
     322             : }
     323             : /*
     324             :  * @-
     325             :  * The M5 wrapper code
     326             :  */
     327             : 
     328             : str
     329           0 : MBMrandom(bat *ret, oid *base, lng *size, int *domain){
     330           0 :         return MBMrandom_seed ( ret, base, size, domain, &int_nil );
     331             : }
     332             : 
     333             : str
     334           0 : MBMrandom_seed(bat *ret, oid *base, lng *size, int *domain, const int *seed){
     335           0 :         BAT *bn = NULL;
     336             : 
     337           0 :         BATrandom(&bn, base, size, domain, *seed);
     338           0 :         if( bn ){
     339           0 :                 BBPkeepref(*ret= bn->batCacheid);
     340           0 :         } else throw(MAL, "microbenchmark.random", OPERATION_FAILED);
     341           0 :         return MAL_SUCCEED;
     342             : }
     343             : 
     344             : 
     345             : str
     346           0 : MBMuniform(bat *ret, oid *base, lng *size, int *domain){
     347           0 :         BAT *bn = NULL;
     348             : 
     349           0 :         BATuniform(&bn, base, size, domain);
     350           0 :         if( bn ){
     351           0 :                 BBPkeepref(*ret= bn->batCacheid);
     352           0 :         } else throw(MAL, "microbenchmark.uniform", OPERATION_FAILED);
     353           0 :         return MAL_SUCCEED;
     354             : }
     355             : 
     356             : str
     357           0 : MBMnormal(bat *ret, oid *base, lng *size, int *domain, int *stddev, int *mean){
     358           0 :         BAT *bn = NULL;
     359           0 :         BATnormal(&bn, base, size, domain, stddev, mean);
     360           0 :         if( bn ){
     361           0 :                 BBPkeepref(*ret= bn->batCacheid);
     362           0 :         } else throw(MAL, "microbenchmark.normal", OPERATION_FAILED);
     363           0 :         return MAL_SUCCEED;
     364             : }
     365             : 
     366             : 
     367             : str
     368           0 : MBMmix(bat *bn, bat *batid)
     369             : {
     370             :         BUN n, r, i;
     371             :         BAT *b;
     372             : 
     373           0 :         if ((b = BATdescriptor(*batid)) == NULL)
     374           0 :                 throw(MAL, "microbenchmark.mix", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     375             : 
     376           0 :         n = BATcount(b);
     377             :         /* mix BUNs randomly */
     378           0 :         for (r = i = 0; i < n; i++) {
     379           0 :                 BUN idx = i + ((r += (BUN) rand()) % (n - i));
     380             :                 int val;
     381             : 
     382           0 :                 val = *(int *) Tloc(b, i);
     383           0 :                 *(int *) Tloc(b, i) = *(int *) Tloc(b, idx);
     384           0 :                 *(int *) Tloc(b, idx) = val;
     385             :         }
     386             : 
     387           0 :         BBPkeepref(*bn= b->batCacheid);
     388             : 
     389           0 :         return MAL_SUCCEED;
     390             : }
     391             : 
     392             : str
     393           0 : MBMskewed(bat *ret, oid *base, lng *size, int *domain, int *skew){
     394           0 :         BAT *bn = NULL;
     395             : 
     396           0 :         BATskewed(&bn, base, size, domain, skew);
     397           0 :         if( bn ){
     398           0 :                 BBPkeepref(*ret= bn->batCacheid);
     399           0 :         } else throw(MAL, "microbenchmark.skewed", OPERATION_FAILED);
     400           0 :         return MAL_SUCCEED;
     401             : }
     402             : 
     403             : #if 0
     404             : 
     405             : #include "mel.h"
     406             : mel_func microbenchmark_init_funcs[] = {
     407             :  command("microbenchmark", "random", MBMrandom, false, "Create a BAT with random integer distribution; domain == nil:int ? [0:RAND_MAX] : [0,domain)", args(1,4, batarg("",int),arg("base",oid),arg("size",lng),arg("domain",int))),
     408             :  command("microbenchmark", "random", MBMrandom_seed, false, "Create a BAT with random integer distribution,\nusing given seed (seed == nil:int -> no seed used);\ndomain == nil:int ? [0:RAND_MAX] : [0,domain)", args(1,5, batarg("",int),arg("base",oid),arg("size",lng),arg("domain",int),arg("seed",int))),
     409             :  command("microbenchmark", "uniform", MBMuniform, false, "Create a BAT with uniform integer distribution", args(1,4, batarg("",int),arg("base",oid),arg("size",lng),arg("domain",int))),
     410             :  command("microbenchmark", "normal", MBMnormal, false, "Create a BAT with a normal integer distribution", args(1,6, batarg("",int),arg("base",oid),arg("size",lng),arg("domain",int),arg("stddev",int),arg("mean",int))),
     411             :  command("microbenchmark", "mix", MBMmix, false, "Mix the BUNs of this BAT", args(1,2, batarg("",int),batarg("b1",int))),
     412             :  command("microbenchmark", "skewed", MBMskewed, false, "Create a BAT with skewed integer distribution", args(1,5, batarg("",int),arg("base",oid),arg("size",lng),arg("domain",int),arg("skew",int))),
     413             :  { .imp=NULL }
     414             : };
     415             : #include "mal_import.h"
     416             : #ifdef _MSC_VER
     417             : #undef read
     418             : #pragma section(".CRT$XCU",read)
     419             : #endif
     420             : LIB_STARTUP_FUNC(init_microbenchmark_mal)
     421             : { mal_module("microbenchmark", NULL, microbenchmark_init_funcs); }
     422             : 
     423             : #endif

Generated by: LCOV version 1.14