Skip to content

Commit

Permalink
(Codegen) Add standard C files
Browse files Browse the repository at this point in the history
  • Loading branch information
Antoine Morvan committed Sep 12, 2018
1 parent 286a04b commit 5911e70
Show file tree
Hide file tree
Showing 16 changed files with 1,387 additions and 1 deletion.
3 changes: 2 additions & 1 deletion plugins/org.ietr.preesm.codegen.xtend/build.properties
Expand Up @@ -43,4 +43,5 @@ bin.includes = META-INF/,\
plugin.xml,\
plugin.properties,\
schema/,\
templates/
templates/,\
stdfiles/
66 changes: 66 additions & 0 deletions plugins/org.ietr.preesm.codegen.xtend/stdfiles/c/clock.c
@@ -0,0 +1,66 @@
/*
============================================================================
Name : clock.c
Author : mpelcat
Version : 1.0
Copyright : CECILL-C
Description : Timing primitive for Preesm Codegen.
============================================================================
*/

#include "clock.h"


#ifdef _WIN32
// clock is not precise at all
#include <windows.h> // for Windows APIs
#include <stdio.h>
#else
#include <stdio.h>
#include <sys/time.h> // for gettimeofday()
#endif


#ifdef _WIN32
LARGE_INTEGER startTimes[MAX_STAMPS];
#else
struct timeval startTimes[MAX_STAMPS];
#endif

double elapsedTimes[MAX_STAMPS];

// Starting to record time for a given stamp
void startTiming(int stamp){
#ifdef _WIN32
QueryPerformanceCounter(&startTimes[stamp]);
#else
gettimeofday(&startTimes[stamp], NULL);
#endif
}

// Stoping to record time for a given stamp. Returns the time in us
unsigned int stopTiming(int stamp){
unsigned int elapsedus = 0;
#ifdef _WIN32
LARGE_INTEGER frequency;
LARGE_INTEGER t2;
QueryPerformanceCounter(&t2);

// get ticks per second
QueryPerformanceFrequency(&frequency);

// compute and print the elapsed time in millisec
elapsedTimes[stamp] = (t2.QuadPart - startTimes[stamp].QuadPart) * 1000.0 / frequency.QuadPart;
#else
struct timeval t2;

gettimeofday(&t2, NULL);

// compute and print the elapsed time in millisec
elapsedTimes[stamp] = (t2.tv_sec - startTimes[stamp].tv_sec) * 1000.0; // sec to ms
elapsedTimes[stamp] += (t2.tv_usec - startTimes[stamp].tv_usec) / 1000.0; // us to ms
#endif

elapsedus = (int)(elapsedTimes[stamp]*1000);
return elapsedus;
}
24 changes: 24 additions & 0 deletions plugins/org.ietr.preesm.codegen.xtend/stdfiles/c/clock.h
@@ -0,0 +1,24 @@
/*
============================================================================
Name : clock.h
Author : mpelcat
Version : 1.0
Copyright : CECILL-C
Description : Timing primitive for Preesm Codegen.
============================================================================
*/

#ifndef CLOCK_H
#define CLOCK_H

// stamps used in clock functions to store data
#define MAX_STAMPS 50
#define CLOCK_STAMP_GENERAL 0

// Starting to record time for a given stamp
void startTiming(int stamp);

// Stoping to record time for a given stamp. Returns the time in us
unsigned int stopTiming(int stamp);

#endif
86 changes: 86 additions & 0 deletions plugins/org.ietr.preesm.codegen.xtend/stdfiles/c/communication.c
@@ -0,0 +1,86 @@
/*
============================================================================
Name : communication.c
Author : kdesnos
Version : 1.0
Copyright : CECILL-C
Description :
============================================================================
*/

#include "communication.h"

// note: rk_ struct and functions comes from
// https://stackoverflow.com/questions/27736618/why-are-sem-init-sem-getvalue-sem-destroy-deprecated-on-mac-os-x-and-w

struct rk_sema {
#ifdef __APPLE__
dispatch_semaphore_t sem;
#else
sem_t sem;
#endif
};


static inline void
rk_sema_init(struct rk_sema *s, int value)
{
#ifdef __APPLE__
dispatch_semaphore_t *sem = &s->sem;

*sem = dispatch_semaphore_create(value);
#else
sem_init(&s->sem, 0, value);
#endif
}

static inline void
rk_sema_wait(struct rk_sema *s)
{

#ifdef __APPLE__
dispatch_semaphore_wait(s->sem, DISPATCH_TIME_FOREVER);
#else
int r;

do {
r = sem_wait(&s->sem);
} while (r == -1);
#endif
}

static inline void
rk_sema_post(struct rk_sema *s)
{

#ifdef __APPLE__
dispatch_semaphore_signal(s->sem);
#else
sem_post(&s->sem);
#endif
}


// 8 local semaphore for each core (1 useless per core)
struct rk_sema interCoreSem[MAX_NB_CORES][MAX_NB_CORES];

void communicationInit(){
int i, j;
for (i = 0; i < MAX_NB_CORES; i++){
for (j = 0; j < MAX_NB_CORES; j++){
rk_sema_init(&interCoreSem[i][j], 0);
}
}
}

void sendStart(int senderID, int receiverID){
rk_sema_post(&interCoreSem[receiverID][senderID]);
}

void sendEnd(){}

void receiveStart(){}

void receiveEnd(int senderID, int receiverID){
rk_sema_wait(&interCoreSem[receiverID][senderID]);
}
68 changes: 68 additions & 0 deletions plugins/org.ietr.preesm.codegen.xtend/stdfiles/c/communication.h
@@ -0,0 +1,68 @@
/*
============================================================================
Name : communication.h
Author : kdesnos
Version : 2.0
Copyright : CECILL-C
Description : Communication primitive for Preesm Codegen.
Currently, primitives were tested only for x86, shared_mem
communications.
============================================================================
*/

#ifndef COMMUNICATION_H
#define COMMUNICATION_H

#ifdef __APPLE__
#include <dispatch/dispatch.h>
#else
#include <semaphore.h>
#endif

/**
* Maximum number of core supported by the communication library.
* This number is used to allocate the table of semaphores used for intercore
* synchronization.
*/
#define MAX_NB_CORES 16

/**
* Initialize the semaphores used for inter-core synchronization.
*/
void communicationInit();

/**
* Non-blocking function called by the sender to signal that a buffer is ready
* to be sent.
*
* @param[in] senderID
* the ID of the sender core
* @param[in] coreID
* the ID of the receiver core
*/
void sendStart(int senderID, int receveirID);

/**
* Blocking function (not for shared_mem communication) called by the sender to
* signal that communication is completed.
*/
void sendEnd();

/**
* Non-blocking function called by the receiver begin receiving the
* data. (not implemented with shared memory communications).
*/
void receiveStart();

/**
* Blocking function called by the sender to wait for the received data
* availability.
*
* @param[in] senderID
* the ID of the sender core
* @param[in] coreID
* the ID of the receiver core
*/
void receiveEnd(int senderID, int receveirID);

#endif
106 changes: 106 additions & 0 deletions plugins/org.ietr.preesm.codegen.xtend/stdfiles/c/dump.c
@@ -0,0 +1,106 @@
/*
============================================================================
Name : dump.c
Author : kdesnos
Version : 1.0
Copyright : CECILL-C
Description : Function called by code generated by the Instrumented C
Printer of Preesm
============================================================================
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "../include/dump.h"

static FILE *ptfile;
static int *bckupNbExec;

void dumpTime(int id,long* dumpBuffer){
dumpBuffer[id] = clock();
}

void initNbExec(int* nbExec, int nbDump){
int i = 0;

bckupNbExec = malloc(nbDump*sizeof(int));
memset(bckupNbExec,0,nbDump*sizeof(int));

if((ptfile = fopen(DUMP_FILE, "a+")) == NULL )
{
fprintf(stderr,"ERROR: Cannot open dump file '%s'\n", DUMP_FILE);
exit(1);
}

// Go to the end:
fseek (ptfile , 0 , SEEK_END);

//printf(";;");
for(i=1; i<nbDump; i++){
*(nbExec+i) = 1;
fprintf(ptfile,"%d;",i);
}
fprintf(ptfile,"\n");
fflush(ptfile);
}

void writeTime(long* dumpBuffer, int nbDump, int* nbExec){
static int stable = 0;
int i ;
int changed = 0;
int nbNotReady = 0;

if(stable != 0) {
printf("--\n");
for(i=1;i< nbDump;i++){
float nbEx = (float)*(nbExec+i);
float res;
nbEx = (nbEx != 0)? 1/nbEx : 0;
res = ((float)dumpBuffer[i]-(float)dumpBuffer[i-1]) * nbEx;
fprintf(ptfile,"%.2f;",res*CLOCKS_PER_SEC );
}
fprintf(ptfile,"\n");
fflush(ptfile);
} else {
for(i=nbDump-1;i>=0;i--){
int nbExecBefore;

dumpBuffer[i] = dumpBuffer[i]-dumpBuffer[i-1];
// We consider that all measures below 5 ms are not precise enough
nbExecBefore = *(nbExec+i);
if(dumpBuffer[i] < 10*1000/CLOCKS_PER_SEC) {
*(nbExec+i) = ceil(*(nbExec+i) * 1.5);
if(*(nbExec+i) > 131072) {
*(nbExec+i) = 131072;
}
}
if(dumpBuffer[i] < 0){
*(nbExec+i) = 0;
}
if(nbExecBefore != *(nbExec+i)){
changed |= 1;
nbNotReady++;

} else {
if(*(nbExec+i)!=0){
bckupNbExec[i] = *(nbExec+i);
*(nbExec+i) = 0;
}
}
}
printf("Ready: %d/%d\n",nbDump-nbNotReady,nbDump);
if(changed == 0) {
stable = 1;
memcpy(nbExec,bckupNbExec,nbDump*sizeof(int));
free(bckupNbExec);
for(i=1;i<nbDump;i++){
fprintf(ptfile,"%d;",*(nbExec+i));
}
fprintf(ptfile,"\n");
fflush(ptfile);
}
}
}

0 comments on commit 5911e70

Please sign in to comment.