File: add_parallel.c

package info (click to toggle)
dxsamples 4.4.0-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 26,340 kB
  • sloc: ansic: 10,079; sh: 8,445; java: 1,772; makefile: 1,102
file content (130 lines) | stat: -rw-r--r-- 2,678 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <dx/dx.h>

static Error DoAdd(Object o, float x);

m_AddParallel(Object *in, Object *out)
{
  Object o = NULL;
  float x;
  
  /* copy the structure of in[0] */
  if (!in[0]) {
    DXSetError(ERROR_BAD_PARAMETER, "missing data parameter");
    goto error;
  }
  o = (Object)DXCopy(in[0], COPY_STRUCTURE);
  if (!o)
    goto error;
  
  /* extract floating point parameter from in[1] (default 0) */
  if (!in[1])
    x = 0;
  else if (!DXExtractFloat(in[1], &x)) {
    DXSetError(ERROR_BAD_PARAMETER, "addend must be a scalar value");
    goto error;
  }
  
  
  /* call DoAdd() to do the recursive traversal */
  DXCreateTaskGroup();
  if (!DoAdd(o, x))
    goto error;
  if (!DXExecuteTaskGroup())
    goto error;
  
  /* successful return */
  out[0] = o;
  return OK;
  
 error:
  DXDelete(o);
  return ERROR;
}


struct arg {
  Field field;
  float x;
};


static Error
  Add_Task(Pointer p)
{
  struct arg *arg = (struct arg *)p;
  Field field;
  float x, *from, *to;
  int i, n, rank, shape[8];
  Array a;
  Type type;
  Category category;
  
  
  /* extract our arguments */
  field = arg->field;
  x = arg->x;
  
  /* extract, typecheck, and get the data from the ``data'' component */
  a = (Array) DXGetComponentValue(field, "data");
  if (!a) {
    DXSetError(ERROR_MISSING_DATA, "field has no data");
    return ERROR;
  }
  DXGetArrayInfo(a,&n,&type,&category,&rank, shape);
  if ((type != TYPE_FLOAT)||(category != CATEGORY_REAL)||(rank != 0)) {
    DXSetError(ERROR_BAD_TYPE, "data is not scalar floating point");
    return ERROR;
  }
  from = (float *) DXGetArrayData(a);
  
  /* create a new array, allocate space in it, put it in the field */
  a = (Array)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0);
  if (!DXAddArrayData(a, 0, n, NULL))
    return ERROR;
  to = (float *) DXGetArrayData(a);
  DXSetComponentValue(field, "data", (Object)a);
  
  /* the loop that actually adds x to obtain the result */
  for (i=0; i<n; i++)
    to[i] = from[i] + x;
  
  /* clean up the field */
  DXChangedComponentValues(field, "data");
  if (!DXEndField(field))
    return ERROR;
  
  return OK;
}


static
  Error
  DoAdd(Object o, float x)
{
  struct arg arg;
  int i, n;
  Object oo;
  
  /* determine the class of the object */
  switch (DXGetObjectClass(o)) {
    
  case CLASS_FIELD:
    
    /* add the task for this field */
    arg.field = (Field)o;
    arg.x = x;
    if (!DXAddTask(Add_Task, &arg, sizeof(arg), 0.0))
      return ERROR;
    break;
    
  case CLASS_GROUP:
    
    /* recursively traverse groups */
    for (i=0; oo=DXGetEnumeratedMember((Group)o, i, NULL); i++)
      if (!DoAdd(oo, x))
	return ERROR;
    break;
  }	
  
  return OK;
}