<commit_before>/* 
* File:    multiplex1_pthreads.c
* CVS:     $Id$
* Author:  <NAME>
*          <EMAIL>
* Mods:    <your name here>
*          <your email address>
*/  

/* This file tests the multiplex pthread functionality */

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <memory.h>
#include <malloc.h>
#include "papi_test.h"
#include "test_utils.h"

#define FLOPS 4000000
#define READS 4000
#define NUM 10
#define NUM_THREADS 4
#define SUCCESS 1
#define FAILURE 0

extern void do_flops(int);
extern void do_reads(int);

extern int TESTS_QUIET; /* Declared in test_utils.c */

void init_papi_pthreads(void)
{
  int retval;

  /* Initialize the library */

  if((retval = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT)
    test_fail(__FILE__,__LINE__,"PAPI_library_init",retval);

  /* Enable multiplexing support */

  if( (retval = PAPI_multiplex_init()) != PAPI_OK )
    test_fail(__FILE__,__LINE__,"PAPI_multiplex_init",retval);
  
  /* Turn on automatic error reporting */

  if ( !TESTS_QUIET )
    if((retval = PAPI_set_debug(PAPI_VERB_ECONT)) != PAPI_OK )
       test_fail(__FILE__,__LINE__,"PAPI_set_debug",retval);

  /* Turn on thread support in PAPI */

  if ((retval=PAPI_thread_init((unsigned long (*)(void))(pthread_self), 0)) != PAPI_OK){
     if (retval == PAPI_ESBSTR)
        test_skip(__FILE__,__LINE__,"PAPI_thread_init",retval);
     else
        test_fail(__FILE__,__LINE__,"PAPI_thread_init",retval);
  }
}

int do_pthreads(void *(*fn)(void *))
{
  int i, rc;
  pthread_attr_t attr;
  pthread_t id[NUM_THREADS];

  pthread_attr_init(&attr);
#ifdef PTHREAD_CREATE_UNDETACHED
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);
#endif
#ifdef PTHREAD_SCOPE_SYSTEM
  pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
#endif

  for (i=0;i<NUM_THREADS;i++)
    {
      rc = pthread_create(&id[i], &attr, fn, NULL);
      if (rc)
	return(FAILURE);
    }
  for (i=0;i<NUM_THREADS;i++)
    pthread_join(id[i], NULL);

  pthread_attr_destroy(&attr);

  return(SUCCESS);
}

/* Tests that PAPI_multiplex_init does not mess with normal operation. */

void *case1_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[2];

  if ((retval = PAPI_create_eventset(&EventSet)) != PAPI_OK )
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

#if defined(sun) && defined(sparc)
  if ((retval = PAPI_add_event(&EventSet, PAPI_TOT_INS))!=PAPI_OK )
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
#else
  if ((retval = PAPI_add_event(&EventSet, PAPI_FP_INS))!=PAPI_OK )
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
#endif
  if((retval = PAPI_add_event(&EventSet, PAPI_TOT_CYC))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET ) {
    printf("case1 thread %4x:",(unsigned)pthread_self());
    test_print_event_header("",EventSet);
    printf("case1 thread %4x:",(unsigned)pthread_self());
    printf(TAB2,"",values[0],values[1]);
  }
  if((retval = PAPI_cleanup_eventset(&EventSet)) !=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_cleanup_eventset",retval);
  
  return((void *)SUCCESS);
}

/* Tests that PAPI_set_multiplex() works before adding events */

void *case2_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[2];

  if((retval = PAPI_create_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

  if((retval = PAPI_set_multiplex(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_set_multiplex",retval);

  if((retval = PAPI_add_event(&EventSet, PAPI_FP_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if((retval = PAPI_add_event(&EventSet, PAPI_TOT_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET ) {
    printf("case2 thread %4x:",(unsigned)pthread_self());
    test_print_event_header("",EventSet);
    printf("case2 thread %4x:",(unsigned)pthread_self());
    printf(TAB2,"",values[0],values[1]);
  }

  if((retval = PAPI_cleanup_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_cleanup_eventset",retval);
  
  return((void *)SUCCESS);
}

/* Tests that PAPI_set_multiplex() works after adding events */

void *case3_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[2];

  if((retval = PAPI_create_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

  if((retval = PAPI_add_event(&EventSet, PAPI_FP_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if((retval = PAPI_add_event(&EventSet, PAPI_TOT_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if((retval = PAPI_set_multiplex(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_set_multiplex",retval);

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET )  {
    printf("case3 thread %4x:",(unsigned)pthread_self());
    test_print_event_header("",EventSet);
    printf("case3 thread %4x:",(unsigned)pthread_self());
    printf(TAB2,"",values[0],values[1]);
  }

  if((retval = PAPI_cleanup_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_cleanup_eventset",retval);
  
  return((void *)SUCCESS);
}

/* Tests that PAPI_set_multiplex() works before/after adding events */

void *case4_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[4];

  if((retval = PAPI_create_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

  if((retval = PAPI_add_event(&EventSet, PAPI_FP_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if((retval = PAPI_add_event(&EventSet, PAPI_TOT_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if((retval = PAPI_set_multiplex(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_set_multiplex",retval);

#if (defined(i386) && defined(linux)) || (defined(_POWER) && defined(_AIX)) || defined(mips) || (defined(__ia64__) && defined(linux))
  if((retval = PAPI_add_event(&EventSet, PAPI_L1_DCM))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
 #if defined(_POWER4)
  if((retval = PAPI_add_event(&EventSet, PAPI_L1_DCA))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
 #else
  if((retval = PAPI_add_event(&EventSet, PAPI_L1_ICM))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
 #endif
#elif  defined(sparc) && defined(sun)
  if((retval = PAPI_add_event(&EventSet, PAPI_LD_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);

  if((retval = PAPI_add_event(&EventSet, PAPI_SR_INS))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
#elif defined(__ALPHA) && defined(__osf__)
  retval = PAPI_add_event(&EventSet, PAPI_BR_CN);
  if (retval != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
  retval = PAPI_add_event(&EventSet, PAPI_RES_STL);
  if (retval != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
#else
#error "Architecture not ported yet"
#endif

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET ) {<commit_msg>Simplified event selection that tries to adapt to the platform in question. Now passes on AMD (instead of being skipped due to missing PAPI_FP_INS). The set of events attempted might need to be modified during regression tests on other platforms. But it should at least be a lot easier to make the right changes now.<commit_after>/* 
* File:    multiplex1_pthreads.c
* CVS:     $Id$
* Author:  <NAME>
*          <EMAIL>
* Mods:    <your name here>
*          <your email address>
*/  

/* This file tests the multiplex pthread functionality */

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <memory.h>
#include <malloc.h>
#include "papi_test.h"
#include "test_utils.h"

#define FLOPS 4000000
#define READS 4000
#define NUM 10
#define NUM_THREADS 4
#define SUCCESS 1
#define FAILURE 0
//#define METRIC PAPI_FP_INS
#define METRIC PAPI_L1_DCM
extern void do_flops(int);
extern void do_reads(int);

extern int TESTS_QUIET; /* Declared in test_utils.c */

#if defined(sparc) && defined(sun)
const static int preset_PAPI_events[PAPI_MPX_DEF_DEG] = { 
  PAPI_TOT_INS, PAPI_TOT_CYC, PAPI_L1_ICM, PAPI_L1_DCM, PAPI_LD_INS,
  PAPI_SR_INS, PAPI_L2_TCM, 0, };
#else
const static int preset_PAPI_events[PAPI_MPX_DEF_DEG] = { 
  PAPI_FP_INS, PAPI_TOT_CYC, PAPI_L1_ICM, PAPI_L1_DCM, PAPI_L2_TCM, 
  PAPI_BR_CN, PAPI_RES_STL, 0, };
#endif
static int PAPI_events[PAPI_MPX_DEF_DEG] = { 0, };
static int num_PAPI_events = 0;

void init_papi_pthreads(void)
{
  int retval;
  const int *inev;
  int *outev;

  /* Initialize the library */

  if((retval = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT)
    test_fail(__FILE__,__LINE__,"PAPI_library_init",retval);

  /* Investigate the set of candidate events */
  num_PAPI_events = 0;
  for(inev=preset_PAPI_events,outev=PAPI_events;*inev;inev++) {
    if(PAPI_query_event(*inev) == PAPI_OK) {
      *outev++=*inev;num_PAPI_events++;
    }
  }
  /* Enable multiplexing support */

  if( (retval = PAPI_multiplex_init()) != PAPI_OK )
    test_fail(__FILE__,__LINE__,"PAPI_multiplex_init",retval);
  
  /* Turn on automatic error reporting */

  if ( !TESTS_QUIET )
    if((retval = PAPI_set_debug(PAPI_VERB_ECONT)) != PAPI_OK )
       test_fail(__FILE__,__LINE__,"PAPI_set_debug",retval);

  /* Turn on thread support in PAPI */

  if ((retval=PAPI_thread_init((unsigned long (*)(void))(pthread_self), 0)) != PAPI_OK){
     if (retval == PAPI_ESBSTR)
        test_skip(__FILE__,__LINE__,"PAPI_thread_init",retval);
     else
        test_fail(__FILE__,__LINE__,"PAPI_thread_init",retval);
  }

}

int do_pthreads(void *(*fn)(void *))
{
  int i, rc;
  pthread_attr_t attr;
  pthread_t id[NUM_THREADS];

  pthread_attr_init(&attr);
#ifdef PTHREAD_CREATE_UNDETACHED
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);
#endif
#ifdef PTHREAD_SCOPE_SYSTEM
  pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
#endif

  for (i=0;i<NUM_THREADS;i++)
    {
      rc = pthread_create(&id[i], &attr, fn, NULL);
      if (rc)
	return(FAILURE);
    }
  for (i=0;i<NUM_THREADS;i++)
    pthread_join(id[i], NULL);

  pthread_attr_destroy(&attr);

  return(SUCCESS);
}

/* Tests that PAPI_multiplex_init does not mess with normal operation. */

void *case1_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[2];

  if ((retval = PAPI_create_eventset(&EventSet)) != PAPI_OK )
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

  for(i=0;i<2;i++) {
    if ((retval = PAPI_add_event(&EventSet, PAPI_events[i]))!=PAPI_OK )
      test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
  }

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET ) {
    printf("case1 thread %4x:",(unsigned)pthread_self());
    test_print_event_header("",EventSet);
    printf("case1 thread %4x:",(unsigned)pthread_self());
    printf(TAB2,"",values[0],values[1]);
  }
  if((retval = PAPI_cleanup_eventset(&EventSet)) !=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_cleanup_eventset",retval);
  
  return((void *)SUCCESS);
}

/* Tests that PAPI_set_multiplex() works before adding events */

void *case2_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[2];

  if((retval = PAPI_create_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

  if((retval = PAPI_set_multiplex(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_set_multiplex",retval);

  for(i=0;i<2;i++) {
    if ((retval = PAPI_add_event(&EventSet, PAPI_events[i]))!=PAPI_OK )
      test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
  }

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET ) {
    printf("case2 thread %4x:",(unsigned)pthread_self());
    test_print_event_header("",EventSet);
    printf("case2 thread %4x:",(unsigned)pthread_self());
    printf(TAB2,"",values[0],values[1]);
  }

  if((retval = PAPI_cleanup_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_cleanup_eventset",retval);
  
  return((void *)SUCCESS);
}

/* Tests that PAPI_set_multiplex() works after adding events */

void *case3_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[2];

  if((retval = PAPI_create_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

  for(i=0;i<2;i++) {
    if ((retval = PAPI_add_event(&EventSet, PAPI_events[i]))!=PAPI_OK )
      test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
  }

  if((retval = PAPI_set_multiplex(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_set_multiplex",retval);

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET )  {
    printf("case3 thread %4x:",(unsigned)pthread_self());
    test_print_event_header("",EventSet);
    printf("case3 thread %4x:",(unsigned)pthread_self());
    printf(TAB2,"",values[0],values[1]);
  }

  if((retval = PAPI_cleanup_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_cleanup_eventset",retval);
  
  return((void *)SUCCESS);
}

/* Tests that PAPI_set_multiplex() works before/after adding events */

void *case4_pthreads(void *arg) 
{
  int retval, i, EventSet = PAPI_NULL;
  long long values[4];

  if((retval = PAPI_create_eventset(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_create_eventset",retval);

  for(i=0;i<2;i++) {
    if ((retval = PAPI_add_event(&EventSet, PAPI_events[i]))!=PAPI_OK )
      test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
  }

  if((retval = PAPI_set_multiplex(&EventSet))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_set_multiplex",retval);

  for(i=2;i<4;i++) {
    if ((retval = PAPI_add_event(&EventSet, PAPI_events[i]))!=PAPI_OK )
      test_fail(__FILE__,__LINE__,"PAPI_add_event",retval);
  }

  if ((retval=PAPI_start(EventSet)) != PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_start",retval);

  for (i=0;i<NUM;i++)
    {
      do_flops(FLOPS);
      do_reads(READS);
    }

  if((retval = PAPI_stop(EventSet, values))!=PAPI_OK)
    test_fail(__FILE__,__LINE__,"PAPI_stop",retval);

  if ( !TESTS_QUIET ) {
{'fraction_non_alphanumeric': 0.1507534584980237, 'fraction_numerical': 0.00846096837944664, 'mean_word_length': 5.464271457085828, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '950701', 'n_tokens_mistral': 6417, 'n_tokens_neox': 6252, 'n_words': 946}