📄 neurolib.c
字号:
/****************************************************************//* *//* Name: neurolib.c *//* *//* Project: NeuroBasic *//* *//* Survey: Contains the declaration of global varables *//* used by all packages (USIC part of the *//* simulator). *//* *//* Author: Urs Mueller *//* Electronics Laboratory, ETH Zuerich *//* Switzerland *//* *//* Created: July 21, 1994 (um) *//* Modified: January 8, 1995 (mk) *//* *//****************************************************************//* system header files */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <musiclib.h>/* NeuroBasic header files */#include "allnobjs.h"#include "allnfcts.h"#include "allhfcts.h"#include "neurolib.h"/* global variables *//********************/int fn_error = ERR_NOERROR; /* error code */char *fn_error_msg = NULL; /* error message */unsigned int randseed = 1;neuro_obj_t neuro_objs[NEURO_OBJS_MAX];trans_buf_t trans_buf = {{NULL, NULL}, {NULL, NULL}, 0, 0};void *piram; /* ^internal DSP memory */MINT dummy;MFLOAT fdummy;comm_def_t mdisk_read_window; /* read window for MDISK */MINT nobj_lastused_read = -1; /* object, that has used last the read window *//**********************************//* global functions and utilities *//**********************************/void tbuf_sync(void *pcons)/*************************/{ /*===== simple Wait_data() =====*/ if (pcons == NULL) { Wait_data(ALL_DATA); return; } /*===== communication from transbuf 0 in action =====*/ if (trans_buf.pdest_buf[0] == pcons) { if (trans_buf.last_used == 0) Wait_data(ALL_DATA); trans_buf.pdest_buf[0] = NULL; return; } /*===== communication from transbuf 1 in action =====*/ if (trans_buf.pdest_buf[1] == pcons) { if (trans_buf.last_used == 1) Wait_data(ALL_DATA); trans_buf.pdest_buf[1] = NULL; return; } /*===== in any other case: Wait_data() =====*/ Wait_data(ALL_DATA);} /* end of tbuf_sync() */void *tbuf_getfree(void *pcons)/*****************************/{ static void *p; if (trans_buf.pdest_buf[trans_buf.last_used] == pcons) trans_buf.pdest_buf[trans_buf.last_used] = NULL; trans_buf.last_used = (trans_buf.last_used == 0) ? 1 : 0; trans_buf.pdest_buf[trans_buf.last_used] = pcons; p = trans_buf.tbuf[trans_buf.last_used]; return p;} /* end of tbuf_getfree() */void *tbuf_getdata(void *pcons)/*****************************/{ if (trans_buf.pdest_buf[0] == pcons && trans_buf.last_used == 0) return trans_buf.tbuf[0]; if (trans_buf.pdest_buf[1] == pcons && trans_buf.last_used == 1) return trans_buf.tbuf[1]; return NULL;} /* end of tbuf_getdata() */static MINT alloc_trans_buf(MINT size)/*==================================*/{ MINT old_size; if (trans_buf.tb_size >= size) return TRUE; old_size = trans_buf.tb_size; if (trans_buf.tbuf[1] != NULL) dfree(trans_buf.tbuf[1]); if (trans_buf.tbuf[0] != NULL) dfree(trans_buf.tbuf[0]); trans_buf.tbuf[0] = NULL; trans_buf.tbuf[1] = NULL; trans_buf.pdest_buf[0] = NULL; trans_buf.pdest_buf[1] = NULL; trans_buf.last_used = 0; trans_buf.tb_size = 0; trans_buf.tbuf[0] = dmalloc(size * sizeof(MFLOAT), MT_PROD_LOW); trans_buf.tbuf[1] = dmalloc(size * sizeof(MFLOAT), MT_PROD_LOW); if (trans_buf.tbuf[0] == NULL || trans_buf.tbuf[1] == NULL) { /* failure */ if (trans_buf.tbuf[1] != NULL) dfree(trans_buf.tbuf[1]); if (trans_buf.tbuf[0] != NULL) dfree(trans_buf.tbuf[0]); trans_buf.tbuf[0] = dmalloc(old_size * sizeof(MFLOAT), MT_PROD_LOW); trans_buf.tbuf[1] = dmalloc(old_size * sizeof(MFLOAT), MT_PROD_LOW); return FALSE; } else { /* success */ trans_buf.tb_size = size; return TRUE; }} /* end of alloc_trans_buf() */static void shrink_trans_buf(void)/*==============================*/{ MINT nobj; MINT trans_buf_max; trans_buf_max = 0; for (nobj = 0; nobj < NEURO_OBJS_MAX; nobj++) { if (neuro_objs[nobj].public.obtype != N_FREE && neuro_objs[nobj].public.trans_buf_size > trans_buf_max) trans_buf_max = neuro_objs[nobj].public.trans_buf_size; } alloc_trans_buf(trans_buf_max);} /* end of shrink_trans_buf() */void free_nobj(MINT nobj)/***********************/{ memset((char*)(neuro_objs+nobj), 0, sizeof(neuro_obj_t)); neuro_objs[nobj].public.obtype = N_FREE; shrink_trans_buf();} /* end of free_nobj() */MINT alloc_nobj(size_t trans_buf_size)/************************************/{ MINT nobj; /*===== find free entry in neuro-object table =====*/ for (nobj = 0; nobj < NEURO_OBJS_MAX && neuro_objs[nobj].public.obtype != N_FREE; nobj++); if (nobj >= NEURO_OBJS_MAX) return NO_OBJECT; /* object table full */ memset((char*)(neuro_objs+nobj), 0, sizeof(neuro_obj_t)); neuro_objs[nobj].public.trans_buf_size = trans_buf_size; /*===== allocate memory for transfer buffer =====*/ if (alloc_trans_buf(trans_buf_size)) return nobj; /*===== no memory for transfer buffer =====*/ memset((char*)(neuro_objs+nobj), 0, sizeof(neuro_obj_t)); neuro_objs[nobj].public.obtype = N_FREE; return NO_OBJECT;} /* end of alloc_nobj() */MINT realloc_nobj(MINT nobj, size_t trans_buf_size)/*************************************************/{ /*===== check neuro-object =====*/ if (nobj >= NEURO_OBJS_MAX || nobj < 0 || neuro_objs[nobj].public.obtype == N_FREE) return NO_OBJECT; /* wrong object */ neuro_objs[nobj].public.trans_buf_size = trans_buf_size; shrink_trans_buf(); return nobj;} /* end of realloc_nobj() */MINT send_string(char *str)/*************************//* pack strings from 32-bit words (MUSIC) to 8-bit words (host) and send it to the host*/{ packed_char_t *pdest, *pd; message_t msg; MINT nwords, slen; slen = strlen(str); nwords = (slen + 1 + 3) / 4; pdest = pd = dmalloc(nwords * sizeof(MINT), MT_SLOW); if (pd == NULL) { msg[0].i = msg[1].i = 0; Wr_to_host(msg, sizeof(msg), WR_ONE); return FALSE; } /*===== pack string =====*/ while (TRUE) { pd->char3 = *str; if (*str++ == 0) break; pd->char2 = *str; if (*str++ == 0) break; pd->char1 = *str; if (*str++ == 0) break; pd->char0 = *str; if (*str++ == 0) break; pd++; } msg[0].i = nwords; msg[1].i = slen; Wr_to_host(msg, sizeof(msg), WR_ONE); Wr_to_host(pdest, nwords * sizeof(MINT), WR_ONE); dfree(pdest); return TRUE;} /* end of send_string() */MFLOAT broadcast_one_value(double value, MINT sender)/***************************************************/{ MFLOAT p, c; comm_def_t window; window.dim.x = window.dim.y = window.dim.z = 1; window.elem_size = sizeof(MFLOAT); if (sender) window.prod.part.x = 1; else window.prod.part.x = 0; window.prod.part.y = 1; window.prod.part.z = 1; window.prod.offset.x = 0; window.prod.offset.y = 0; window.prod.offset.z = 0; window.prod.nelements = window.prod.part.x * window.prod.part.y * window.prod.part.z; if (window.prod.nelements == 0) window.prod.offset = window.dim; Complete_cons_window(&window, ALL_DISTR, 0, 0, 0); Init_comm(&window, &p, &c, COMM_NORM); p = value; Data_ready(ALL_DATA); Wait_data(ALL_DATA); return c;} /* end of broadcast_one_value() */MINT setup_load(MINT ndim, MINT xdim, MINT ydim, MINT zdim, MINT block_size, MINT format)/*=======================================================*/{ message_t msg; msg[0].i = ndim; msg[1].i = xdim; msg[2].i = ydim; msg[3].i = zdim; msg[4].i = block_size; msg[5].i = format; Wr_to_host(msg, sizeof(msg), WR_ONE); Rd_from_host(msg, sizeof(msg), RD_ALL); if (msg[0].i < ERR_NOERROR) { fn_error = (int)msg[0].i; return FALSE; /* abort */ } else return TRUE;} /* end of setup_load() */MINT setup_save(MINT ndim, MINT xdim, MINT ydim, MINT zdim, MINT block_size)/*=======================================================*/{ message_t msg; msg[0].i = ndim; msg[1].i = xdim; msg[2].i = ydim; msg[3].i = zdim; msg[4].i = block_size; Wr_to_host(msg, sizeof(msg), WR_ONE); Rd_from_host(msg, sizeof(msg), RD_ALL); if (msg[0].i < ERR_NOERROR) { fn_error = msg[0].i; return FALSE; /* abort */ } else return TRUE;} /* end of setup_save() *//*******************//* neuro-functions *//*******************/MINT release(MINT nobj)/*********************/{ MINT i; if (nobj != NO_OBJECT) { /* release a single neuro-object */ if (nobj < 0 || nobj >= NEURO_OBJS_MAX) { fn_error = ERR_NOOBJ; } else if (neuro_objs[nobj].public.obtype != N_FREE) { if (neuro_objs[nobj].public.fn_release != NULL) { neuro_objs[nobj].public.fn_release(nobj); } else { fn_error = ERR_GERROR; fn_error_msg = "release() does not work with this object type"; } } } else { /* release all neuro-objects */ for (i = 0; i < NEURO_OBJS_MAX; i++) release(i); } return 0;} /* end of release() */MINT load(MINT nobj, MINT pfilename)/**********************************/{ message_t msg; if (nobj < 0 || nobj > NEURO_OBJS_MAX || neuro_objs[nobj].public.obtype == N_FREE) { fn_error = ERR_NOOBJ; return 0; } if (neuro_objs[nobj].public.fn_load == NULL) { fn_error = ERR_GERROR; fn_error_msg = "load() does not work with this object type"; return 0; } msg[0].i = C_USER_FCT; msg[1].i = BASIC_LOAD; /* universal load function */ msg[2].i = pfilename; Wr_to_host(msg, sizeof(msg), WR_ONE); return neuro_objs[nobj].public.fn_load(nobj);} /* end of load() */MINT save(MINT nobj, MINT pfilename, MINT format)/***********************************************/{ message_t msg; if (nobj < 0 || nobj > NEURO_OBJS_MAX || neuro_objs[nobj].public.obtype == N_FREE) { fn_error = ERR_NOOBJ; return 0; } if (neuro_objs[nobj].public.fn_save == NULL) { fn_error = ERR_GERROR; fn_error_msg = "save() does not work with this object type"; return 0; } msg[0].i = C_USER_FCT; msg[1].i = BASIC_SAVE; /* universal save function */ msg[2].i = pfilename; msg[3].i = format; Wr_to_host(msg, sizeof(msg), WR_ONE); return neuro_objs[nobj].public.fn_save(nobj);} /* end of save() */MINT nput(MINT nobj, MINT nx, MINT ny, MFLOAT value)/**************************************************/{ if (nobj < 0 || nobj > NEURO_OBJS_MAX || neuro_objs[nobj].public.obtype == N_FREE) { fn_error = ERR_NOOBJ; } else if (neuro_objs[nobj].public.fn_nput == NULL) { fn_error = ERR_GERROR; fn_error_msg = "nput() does not work with this object type"; } else neuro_objs[nobj].public.fn_nput(nobj, nx, ny, value); return 0;} /* end of nput() */MFLOAT nget(MINT nobj, MINT nx, MINT ny)/**************************************/{ if (nobj < 0 || nobj > NEURO_OBJS_MAX || neuro_objs[nobj].public.obtype == N_FREE) { fn_error = ERR_NOOBJ; return 0.0; } if (neuro_objs[nobj].public.fn_nget == NULL) { fn_error = ERR_GERROR; fn_error_msg = "nget() does not work with this object type"; return 0.0; } return neuro_objs[nobj].public.fn_nget(nobj, nx, ny);} /* end of nget() */MINT show(MINT nobj)/******************/{ message_t msg; if (nobj < 0 || nobj > NEURO_OBJS_MAX || neuro_objs[nobj].public.obtype == N_FREE) { fn_error = ERR_NOOBJ; } else if (neuro_objs[nobj].public.fn_save == NULL) { fn_error = ERR_GERROR; fn_error_msg = "show() does not work with this object type"; } else { msg[0].i = C_USER_FCT; msg[1].i = BASIC_SHOW; /* universal display function */ Wr_to_host(msg, sizeof(msg), WR_ONE); return neuro_objs[nobj].public.fn_save(nobj); } return 0;} /* end of save() */MINT randomize(MINT nobj, MFLOAT range)/*************************************/{ if (nobj < 0 || nobj > NEURO_OBJS_MAX || neuro_objs[nobj].public.obtype == N_FREE) { fn_error = ERR_NOOBJ; } else if (neuro_objs[nobj].public.fn_rand == NULL) { fn_error = ERR_GERROR; fn_error_msg = "randomize() does not work with this object type"; } else { return neuro_objs[nobj].public.fn_rand(nobj, range); } return 0;} /* end of randomize() */MINT rnd(MINT range)/******************/{ srand(randseed); randseed = rand(); return (MINT)((MFLOAT)rand() / RAND_MAX * range);} /* end of rnd() */MINT random_seed(MINT seed)/*************************/{ randseed = (unsigned int)seed; return 0;} /* end of random_seed() */MINT rseq(MINT newl)/******************//* if newl < 0 it produces a random sequence of size abs(newl) starting from 0 where each number appears exactely once. If newl >=0 it picks the newl-th of these values.*/{ static MINT *ps = NULL; /* ^random sequence */ static MINT slength = 0; /* length of sequence */ MINT i; /* counter */ MINT r, tmp; if (newl < 0) { /* Initialize a new random sequence */ newl = -newl; /* make it positive */ if (ps != NULL) dfree(ps); ps = dmalloc(newl * sizeof(MINT), MT_SLOW); if (ps == NULL) { slength = 0; fn_error = ERR_NOMEM; return -1; } for (i = 0; i < newl; i++) ps[i] = i; for (i = newl-1; i >= 0; i--) { r = (MINT)(rand() / ((MFLOAT)RAND_MAX + 1) * (i + 1)); tmp = ps[r]; ps[r] = ps[i]; ps[i] = tmp; } slength = newl; return -1; } else { /* Pick an element of the existing sequence */ if (newl >= slength) { fn_error = ERR_PARCONF; return -1; } else return ps[newl]; }} /* end of rseq() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -