Arax -8d09c51940345c86062e8ef2427c705ae66e5926
A Runtime Framework for Decoupling Applications from Heterogeneous Accelerators
Loading...
Searching...
No Matches
impl.c
Go to the documentation of this file.
1#include <arax.h>
2#include <arax_pipe.h>
3#include "core/arax_data.h"
4#include "utils/config.h"
5#include "utils/system.h"
6#include "utils/timer.h"
7#include <sys/mman.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <stdlib.h>
11#include <string.h>
12
13const char *arax_version = "VT_VERSION " ARAX_GIT_REV " - " ARAX_GIT_BRANCH;
14
15struct
16{
18 char shm_file[1024];
19 uint64_t threads;
20 uint64_t instance_uid;
21 uint64_t task_uid;
22 volatile uint64_t initialized;
25 int fd;
26} arax_state =
27{ (void *) CONF_ARAX_MMAP_BASE, { '\0' }, 0, 0, 0, 0, 0, NULL, 0 };
28
29#define arax_pipe_get() arax_state.vpipe
30
31#define GO_FAIL(MSG) ({ err = __LINE__; err_msg = MSG; goto FAIL; })
32
33arax_pipe_s* _arax_init(int wait_controller)
34{
35 arax_pipe_s *shm_addr = 0;
36 int err = 0;
37 size_t shm_size = 0;
38 size_t shm_off = 0;
39 int shm_trunc = 0;
40 int shm_ivshmem = 0;
41 int enforce_version = 0;
42 const char *err_msg = "No Error Set";
43
44 if (__sync_fetch_and_add(&(arax_state.threads), 1) != 0) { // I am not the first but stuff might not yet be initialized
45 while (!arax_state.initialized); // wait for initialization
46 goto GOOD;
47 }
48
49 arax_state.config_path = utils_config_alloc_path(ARAX_CONFIG_FILE);
50
51 printf("Config:%s\n", (utils_config_get_source() == CONFIG_FILE) ? ARAX_CONFIG_FILE : "ARAX_CONF");
52
53 /* Required Confguration Keys */
54 if (!utils_config_get_str(arax_state.config_path, "shm_file", arax_state.shm_file, 1024, 0) )
55 GO_FAIL("No shm_file set in config");
56
57 /* Default /4 of system memory*/
58 shm_size = system_total_memory() / 4;
59
60 utils_config_get_size(arax_state.config_path, "shm_size", &shm_size, shm_size);
61
62 if (!shm_size || shm_size > system_total_memory() )
63 GO_FAIL("shm_size exceeds system memory");
64
65 /* Optional Confguration Keys */
66 utils_config_get_size(arax_state.config_path, "shm_off", &shm_off, 0);
67 utils_config_get_bool(arax_state.config_path, "shm_trunc", &shm_trunc, 1);
68 utils_config_get_bool(arax_state.config_path, "shm_ivshmem", &shm_ivshmem, 0);
69 utils_config_get_bool(arax_state.config_path, "enforce_version", &enforce_version, 1);
70
71 if (shm_ivshmem) {
72 shm_off += 4096; /* Skip register section */
73 shm_trunc = 0; /* Don't truncate ivshm device */
74 }
75
76 if (system_mmap((void **) &(arax_state.vpipe), &(arax_state.fd), arax_state.shm_file, shm_size, shm_off,
77 shm_trunc))
78 {
79 if (arax_state.fd < 0)
80 GO_FAIL("Could not open shm_file");
81 if (arax_state.vpipe == NULL)
82 GO_FAIL("Could not first mmap shm_file");
83 }
84
85 shm_addr = arax_pipe_mmap_address(arax_state.vpipe);
86
88 if (shm_addr != arax_state.vpipe) {
89 munmap(arax_state.vpipe, arax_state.vpipe->shm_size); // unmap misplaced map.
90
91 arax_state.vpipe = shm_addr; // Place mmap where we want it
92
93 if (system_mmap((void **) &(arax_state.vpipe), &(arax_state.fd), arax_state.shm_file, shm_size, shm_off,
94 0) || arax_state.vpipe != shm_addr)
95 GO_FAIL("Could not mmap shm_file in proper address");
96 }
97 } else { // Proccess was already mmaped (although we forgot about it :-S
98 arax_state.vpipe = shm_addr;
99 }
100
101 arax_state.vpipe = arax_pipe_init(arax_state.vpipe, shm_size, enforce_version);
102
103 if (!arax_state.vpipe)
104 GO_FAIL("Could not initialize arax_pipe");
105
106 arax_state.initialy_available = arax_pipe_get_available_size(arax_state.vpipe);
107
108 async_meta_init_always(&(arax_state.vpipe->async) );
109 printf("ShmFile:%s\n", arax_state.shm_file);
110 printf("ShmLocation:%p\n", arax_state.vpipe);
111 printf("ShmSize:%zu\n", arax_state.vpipe->shm_size);
112 arax_state.instance_uid = __sync_fetch_and_add(&(arax_state.vpipe->last_uid), 1);
113 printf("InstanceUID:%zu\n", arax_state.instance_uid);
114 arax_state.initialized = 1;
115GOOD:
116 if (wait_controller) {
117 async_condition_lock(&(arax_state.vpipe->cntrl_ready_cond));
118 while (arax_state.vpipe->cntrl_ready == 0)
119 async_condition_wait(&(arax_state.vpipe->cntrl_ready_cond));
120 async_condition_unlock(&(arax_state.vpipe->cntrl_ready_cond));
121 }
122 return arax_state.vpipe;
123
124FAIL:
125 printf("%c[31mprepare_arax Failed on line %d (conf:%s,file:%s,shm:%p)\n\
126 Why:%s%c[0m\n", 27, err, ARAX_CONFIG_FILE, arax_state.shm_file,
127 arax_state.vpipe, err_msg, 27);
128 munmap(arax_state.vpipe, arax_state.vpipe->shm_size);
129 exit(1);
130} /* arax_task_init */
131
133{
134 // All applications will wait for the controller/server initialization.
135 return _arax_init(1);
136}
137
142
144{
145 arax_state.vpipe->cntrl_ready = 1;
146 async_condition_notify(&(arax_state.vpipe->cntrl_ready_cond));
147}
148
149#undef GO_FAIL
150
152{
153 return arax_state.instance_uid;
154}
155
157{
158 int last;
159
160 if (arax_state.vpipe) {
161 if (__sync_fetch_and_add(&(arax_state.threads), -1) == 1) { // Last thread of process
162 last = arax_pipe_exit(arax_state.vpipe);
163
164 if (last) {
165 size_t available = arax_pipe_get_available_size(arax_state.vpipe);
166 arax_assert(available == arax_state.initialy_available);
167
168 if (available != arax_state.initialy_available) {
169 printf("\033[1;31mERROR : shm LEAK !!\n\033[0m");
170 }
171 }
172
174 munmap(arax_state.vpipe, arax_state.vpipe->shm_size);
175 arax_state.vpipe = (void *) CONF_ARAX_MMAP_BASE;
176
178 printf("arax_pipe_exit() = %d\n", last);
179 close(arax_state.fd);
180 arax_state.fd = 0;
181 if (last) {
182 if (!arax_clean() )
183 printf("Could not delete \"%s\"\n", arax_state.shm_file);
184 }
185 }
186 } else {
187 fprintf(stderr,
188 "WARNING:arax_exit() called with no matching\
189 call to arax_init()!\n");
190 }
191} /* arax_exit */
192
194{
195 char shm_file[1024];
196
197 char *config_path = utils_config_alloc_path(ARAX_CONFIG_FILE);
198
199 if (!utils_config_get_str(config_path, "shm_file", shm_file, 1024, 0) )
200 arax_assert(!"No shm_file set in config");
201
202 int ret = shm_unlink(shm_file);
203
205
206 return ret == 0;
207}
208
210{
211 arax_assert(phys);
212 arax_assert(vaccel);
213 arax_vaccel_s *acl = (arax_vaccel_s *) vaccel;
214
215 arax_assert(acl);
216 arax_accel_add_vaccel(phys, acl);
217}
218
220
221int arax_accel_list(arax_accel_type_e type, int physical, arax_accel ***accels)
222{
225 utils_list_s *acc_list;
226
227 arax_accel_s **acl = 0;
228 int accel_count = 0;
229 arax_object_type_e ltype;
230
231
232 if (physical)
233 ltype = ARAX_TYPE_PHYS_ACCEL;
234 else
235 ltype = ARAX_TYPE_VIRT_ACCEL;
236
238
239 acc_list =
240 arax_object_list_lock(&(vpipe->objs), ltype);
241
242 if (accels) { /* Want the accels */
243 if (*accels)
245 *accels = malloc( (acc_list->length + 1) * sizeof(arax_accel *) );
246 acl = (arax_accel_s **) *accels;
247 }
248
249 if (physical) {
250 arax_accel_s *accel = 0;
251 utils_list_for_each(*acc_list, itr){
252 accel = (arax_accel_s *) itr->owner;
253 if (!type || accel->type == type) {
254 accel_count++;
255 if (acl) {
256 arax_object_ref_inc(&(accel->obj));
257 *acl = accel;
258 acl++;
259 }
260 }
261 }
262 } else {
263 arax_vaccel_s *accel = 0;
264 utils_list_for_each(*acc_list, itr){
265 accel = (arax_vaccel_s *) itr->owner;
266 if (!type || accel->type == type) {
267 accel_count++;
268 if (acl) {
269 arax_object_ref_inc(&(accel->obj));
270 *acl = (arax_accel_s *) accel;
271 acl++;
272 }
273 }
274 }
275 }
276 if (acl)
277 *acl = 0; // delimiter
278 arax_object_list_unlock(&(vpipe->objs), ltype);
279
280 return accel_count;
281} /* arax_accel_list */
282
284{
285 arax_object_s **itr = (arax_object_s **) accels;
286
287 while (*itr) {
289 itr++;
290 }
291 free(accels);
292}
293
295{
296 arax_object_s **itr = (arax_object_s **) accels;
297
298 while (*itr) {
300 itr++;
301 }
302 free(accels);
303}
304
306{
307 arax_accel_s *_accel;
308
309 _accel = accel;
310
311 return _accel->type;
312}
313
315{
316 arax_accel_s *_accel;
318
319 _accel = accel;
320
321 switch (_accel->obj.type) {
323 ret = arax_accel_get_stat(_accel, stat);
324 break;
326 ret = arax_vaccel_get_stat((arax_vaccel_s *) _accel, stat);
327 break;
328 default:
329 ret = accel_failed; /* Not very 'correct' */
330 }
331
332 return ret;
333}
334
336{
338 arax_accel_s *_accel;
339 int return_value = 0;
340
341
343
344 _accel = *accel;
345
346 if (_accel->obj.type == ARAX_TYPE_PHYS_ACCEL) {
347 *accel = arax_vaccel_init(vpipe, "FILL", _accel->type, _accel);
348 return_value = 1;
349 }
350
351 return return_value;
352}
353
355{
357 arax_accel_s *_accel = 0;
358
360
361 _accel = (arax_accel_s *) arax_vaccel_init(vpipe, "FILL", type, 0);
362
363 return (arax_accel *) _accel;
364}
365
367{
368 arax_vaccel_s *_accel;
369
370 _accel = *accel;
371
372 switch (_accel->obj.type) {
375 arax_object_ref_dec(&(_accel->obj));
376 *accel = 0;
377 return;
378
379 default:
380 arax_assert(!"Non accelerator type passed in arax_accel_release");
381 }
382}
383
384arax_proc* arax_proc_register(const char *func_name)
385{
387 arax_proc_s *proc = 0;
388
389
391 proc = arax_pipe_find_proc(vpipe, func_name);
392
393 if (!proc) { /* Proc has not been declared */
394 proc = arax_proc_init(&(vpipe->objs), func_name);
395 }
396
397 return proc;
398}
399
400arax_proc* arax_proc_get(const char *func_name)
401{
403 arax_proc_s *proc = arax_pipe_find_proc(vpipe, func_name);
404
405 if (proc)
406 arax_object_ref_inc(&(proc->obj));
407 else
408 fprintf(stderr, "Proc %s not found!\n", func_name);
409
410 return proc;
411}
412
414{
415 arax_proc_s *proc = func;
416 /* Decrease user count */
417 int return_value = arax_object_ref_dec(&(proc->obj));
418
419 return return_value;
420}
421
422int check_semantics(size_t in_count, arax_data **input, size_t out_count,
423 arax_data **output)
424{
425 size_t io_cnt;
426 size_t dup_cnt;
427 size_t all_io = out_count + in_count;
428 arax_data_s *temp_data_1 = 0;
429 arax_data_s *temp_data_2 = 0;
430
431 for (io_cnt = 0; io_cnt < all_io; io_cnt++) {
432 // Choose from input or output
433 if (io_cnt < in_count)
434 temp_data_1 = input[io_cnt];
435 else
436 temp_data_1 = output[io_cnt - in_count];
437 // check Validity temp_data_1
438 if (!temp_data_1) {
439 fprintf(stderr, "NULL input #%lu\n", io_cnt);
440 return 0;
441 }
442 if (temp_data_1->obj.type != ARAX_TYPE_DATA) {
443 fprintf(stderr, "Input #%lu not valid data\n", io_cnt);
444 return 0;
445 }
446 // Check duplicates
447 for (dup_cnt = 0; dup_cnt < all_io; dup_cnt++) {
448 // Choose from input or output
449 if (dup_cnt < in_count)
450 temp_data_2 = input[dup_cnt];
451 else
452 temp_data_2 = output[dup_cnt - in_count];
453 // check Validity temp_data_2
454 if (!temp_data_2) {
455 fprintf(stderr, "NULL input #%lu\n", dup_cnt);
456 return 0;
457 }
458 if (temp_data_2->obj.type != ARAX_TYPE_DATA) {
459 fprintf(stderr, "Input #%lu not valid data\n", dup_cnt);
460 return 0;
461 }
462 }
463 }
464 return 1;
465} /* check_semantics */
466
467arax_task* arax_task_issue(arax_accel *accel, arax_proc *proc, const void *host_init, size_t host_size,
468 size_t in_count, arax_data **dev_in, size_t out_count,
469 arax_data **dev_out)
470{
471 // printf("%s %s\n",__func__, ((arax_proc_s*)proc)->obj.name) ;
472
474 arax_task_msg_s *task;
475
476 arax_assert(check_semantics(in_count, dev_in, out_count, dev_out));
477
478 task = arax_task_alloc(vpipe, accel, proc, host_size, in_count, dev_in, out_count, dev_out);
479
480 arax_assert(task);
481
482 if (host_size && host_init)
483 memcpy(arax_task_host_data(task, host_size), host_init, host_size);
484
485 arax_task_submit(task);
486
487 return task;
488} /* arax_task_issue */
489
491 size_t host_size, size_t in_count, arax_data **dev_in, size_t out_count,
492 arax_data **dev_out)
493{
494 arax_task *task = arax_task_issue(accel, proc, host_init, host_size, in_count, dev_in, out_count, dev_out);
495 arax_task_state_e status = arax_task_wait(task);
496
497 arax_task_free(task);
498
499 return status;
500}
501
503{
504 arax_task_msg_s *_task = task;
505 arax_task_state_e ret = 0;
506
507 ret = _task->state;
508
509 if (stats)
510 memcpy(stats, &(_task->stats), sizeof(*stats));
511
512 return ret;
513}
514
516{
517 arax_task_msg_s *_task = task;
518
519 arax_task_wait_done(_task);
520
521 return _task->state;
522}
523
525{
526 arax_task_msg_s *_task = task;
527
528 arax_object_ref_dec(&(_task->obj));
529}
530
532{
534
535 arax_data_s *vd = arax_data_init(vpipe, size);
536
537 return vd;
538}
struct arax_pipe arax_pipe_s
void arax_task
Definition arax_types.h:51
enum arax_accel_state arax_accel_state_e
void arax_accel
Definition arax_types.h:9
enum arax_accel_type arax_accel_type_e
void arax_proc
Definition arax_types.h:14
struct arax_task_stats arax_task_stats_s
arax_accel_type
Definition arax_types.h:83
arax_task_state_e
Definition arax_types.h:62
struct arax_accel_stats arax_accel_stats_s
@ accel_failed
Definition arax_types.h:43
void * arax_buffer_s
Definition arax_types.h:102
void arax_data
Definition arax_types.h:56
#define arax_assert(EXPR)
Definition arax_assert.h:7
@ CONFIG_FILE
Definition config.h:143
struct utils_list_node utils_list_node_s
#define utils_list_for_each(list, itr)
Definition list.h:96
enum arax_object_type arax_object_type_e
@ ARAX_TYPE_DATA
Definition arax_object.h:19
@ ARAX_TYPE_VIRT_ACCEL
Definition arax_object.h:17
@ ARAX_TYPE_PHYS_ACCEL
Definition arax_object.h:16
struct arax_task_msg arax_task_msg_s
void async_condition_wait(async_condition_s *cond)
void async_condition_unlock(async_condition_s *cond)
void async_condition_notify(async_condition_s *cond)
void async_meta_init_always(async_meta_s *meta)
void async_condition_lock(async_condition_s *cond)
arax_pipe_s * _arax_init(int wait_controller)
Definition impl.c:33
uint64_t instance_uid
Definition impl.c:20
volatile uint64_t initialized
Definition impl.c:22
char shm_file[1024]
Definition impl.c:18
int check_semantics(size_t in_count, arax_data **input, size_t out_count, arax_data **output)
Definition impl.c:422
#define arax_pipe_get()
Definition impl.c:29
char * config_path
Definition impl.c:24
arax_pipe_s * vpipe
Definition impl.c:17
uint64_t arax_instance_uid()
Definition impl.c:151
void arax_accel_list_free_pre_locked(arax_accel **accels)
Definition impl.c:294
void arax_controller_init_done()
Definition impl.c:143
uint64_t task_uid
Definition impl.c:21
struct @173207265353054203374042000231016266064377276100 arax_state
int fd
Definition impl.c:25
#define GO_FAIL(MSG)
Definition impl.c:31
arax_pipe_s * arax_controller_init_start()
Definition impl.c:138
uint64_t threads
Definition impl.c:19
size_t initialy_available
Definition impl.c:23
const char * arax_version
Definition impl.c:13
arax_accel_state_e arax_accel_get_stat(arax_accel_s *accel, arax_accel_stats_s *stat)
Definition arax_accel.c:89
void arax_accel_add_vaccel(arax_accel_s *accel, arax_vaccel_s *vaccel)
Definition arax_accel.c:108
arax_data_s * arax_data_init(arax_pipe_s *vpipe, size_t size)
Definition arax_data.c:16
int arax_object_ref_dec_pre_locked(arax_object_s *obj)
void arax_object_ref_inc(arax_object_s *obj)
utils_list_s * arax_object_list_lock(arax_object_repo_s *repo, arax_object_type_e type)
void arax_object_list_unlock(arax_object_repo_s *repo, arax_object_type_e type)
int arax_object_ref_dec(arax_object_s *obj)
arax_proc_s * arax_pipe_find_proc(arax_pipe_s *pipe, const char *name)
Definition arax_pipe.c:219
int arax_pipe_have_to_mmap(arax_pipe_s *pipe, int pid)
Definition arax_pipe.c:126
int arax_pipe_exit(arax_pipe_s *pipe)
Definition arax_pipe.c:241
void arax_pipe_mark_unmap(arax_pipe_s *pipe, int pid)
Definition arax_pipe.c:148
void * arax_pipe_mmap_address(arax_pipe_s *pipe)
Definition arax_pipe.c:165
size_t arax_pipe_get_available_size(arax_pipe_s *pipe)
Definition arax_pipe.c:265
arax_pipe_s * arax_pipe_init(void *mem, size_t size, int enforce_version)
Definition arax_pipe.c:5
arax_proc_s * arax_proc_init(arax_object_repo_s *repo, const char *name)
Definition arax_proc.c:4
void arax_task_wait_done(arax_task_msg_s *msg)
Definition arax_task.c:77
arax_task_msg_s * arax_task_alloc(arax_pipe_s *vpipe, arax_accel *accel, arax_proc *proc, size_t host_size, int ins, arax_data **dev_in, int outs, arax_data **dev_out)
Definition arax_task.c:7
void * arax_task_host_data(arax_task_msg_s *task, size_t size)
Definition arax_task.c:51
void arax_task_submit(arax_task_msg_s *task)
Definition arax_task.c:64
arax_accel_state_e arax_vaccel_get_stat(arax_vaccel_s *accel, arax_accel_stats_s *stat)
arax_vaccel_s * arax_vaccel_init(arax_pipe_s *pipe, const char *name, arax_accel_type_e type, arax_accel_s *accel)
Definition arax_vaccel.c:3
enum utils_config_source utils_config_get_source()
Definition config.c:242
int utils_config_get_str(char *path, const char *key, char *value, size_t value_size, const char *def_val)
Definition config.c:164
int utils_config_get_size(char *path, const char *key, size_t *value, size_t def_val)
Definition config.c:226
void utils_config_free_path(char *path)
Definition config.c:128
int utils_config_get_bool(char *path, const char *key, int *value, int def_val)
Definition config.c:178
char * utils_config_alloc_path(const char *path)
Definition config.c:94
int system_process_id()
Definition system.c:91
size_t system_total_memory()
Definition system.c:13
int system_mmap(void **base, int *fd, const char *file, size_t shm_size, size_t shm_off, int truncate)
Definition system.c:37
int arax_clean()
Definition impl.c:193
void arax_exit()
Definition impl.c:156
arax_pipe_s * arax_init()
Definition impl.c:132
arax_accel * arax_accel_acquire_type(arax_accel_type_e type)
Definition impl.c:354
void arax_accel_set_physical(arax_accel *vaccel, arax_accel *phys)
Definition impl.c:209
void arax_accel_list_free(arax_accel **accels)
Definition impl.c:283
void arax_accel_release(arax_accel **accel)
Definition impl.c:366
int arax_accel_list(arax_accel_type_e type, int physical, arax_accel ***accels)
Definition impl.c:221
arax_accel_state_e arax_accel_stat(arax_accel *accel, arax_accel_stats_s *stat)
Definition impl.c:314
int arax_accel_acquire_phys(arax_accel **accel)
Definition impl.c:335
int arax_proc_put(arax_proc *func)
Definition impl.c:413
arax_proc * arax_proc_get(const char *func_name)
Definition impl.c:400
arax_proc * arax_proc_register(const char *func_name)
Definition impl.c:384
arax_task_state_e arax_task_issue_sync(arax_accel *accel, arax_proc *proc, void *host_init, size_t host_size, size_t in_count, arax_data **dev_in, size_t out_count, arax_data **dev_out)
Definition impl.c:490
void arax_task_free(arax_task *task)
Definition impl.c:524
arax_task * arax_task_issue(arax_accel *accel, arax_proc *proc, const void *host_init, size_t host_size, size_t in_count, arax_data **dev_in, size_t out_count, arax_data **dev_out)
Definition impl.c:467
arax_task_state_e arax_task_wait(arax_task *task)
Definition impl.c:515
arax_task_state_e arax_task_stat(arax_task *task, arax_task_stats_s *stats)
Definition impl.c:502
arax_buffer_s ARAX_BUFFER(size_t size)
Definition impl.c:531
arax_object_s obj
Definition arax_accel.h:16
arax_accel_type_e type
Definition arax_accel.h:17
arax_object_s obj
Definition arax_data.h:38
arax_object_type_e type
Definition arax_object.h:45
arax_object_s obj
Definition arax_proc.h:17
arax_object_s obj
Definition arax_task.h:11
arax_task_state_e state
Definition arax_task.h:19
arax_task_stats_s stats
Definition arax_task.h:20
arax_object_s obj
Definition arax_vaccel.h:31
arax_accel_type_e type
Definition arax_vaccel.h:32
void * owner
Definition list.h:14
size_t length
Definition list.h:19