/** * pre-OpenCL 1.1 compatibility macros */ #if __OPENCL_VERSION__ <= CL_VERSION_1_0 #define atomic_add(p, v) atom_add(p, v) #define atomic_inc(p) atom_inc(p) #endif typedef struct { int width; int height; float growthRate; float diffusionRate; float diffusionThreshold; float mortalityRate; int speciality; } CollemWorld; #define PREF_FOREST 1 #define PREF_CULTURAL 2 #define PREF_CITY 3 #define MATCH_PREFERENCE(pref, type) \ ((pref == PREF_FOREST && (type == 6 || type == 7 || type == 8 || type == 10)) \ || ((pref == PREF_CULTURE && (type == 3 || type == 4 || type == 5)) \ || ((pref == PREF_CITY && (type == 1) /* kernel void collembola(global int * patches, int width) { const int i = get_global_id(0); const int j = get_global_id(1); //patches[i * width + j] = -patches[i * width + j]; // Diffusion }*/ #define CELL(world, values, x, y) (values[x * world->width + y]) #define OVERFLOW(world, values, x, y)(values[(x + 1) * (world->width + 2) + 1 + y]) kernel void newArrivals( global CollemWorld *world, global int *populations, global int *patchesOwners, global int *plotsPopulations, global int *plotsSurfaces) { const int i = get_global_id(0); const int j = get_global_id(1); const int plotId = CELL(world, patchesOwners, i, j); if (plotId == -1) return; CELL(world, populations, i, j) = CELL(world, populations, i, j) + (world->growthRate * plotsPopulations[plotId]) / plotsSurfaces[plotId]; } kernel void reproduction( global CollemWorld *world, global int *populations, global int *patchesOwners, global int *plotsPopulations) { const int i = get_global_id(0); const int j = get_global_id(1); const int plotId = CELL(world, patchesOwners, i, j); if (plotId == -1) return; atomic_add(plotsPopulations + plotId, CELL(world, populations, i, j)); } kernel void diffusion( global CollemWorld *world, global int *populations, global int *overflows, global int *newPopulations) { const int i = get_global_id(0); const int j = get_global_id(1); // Determine if we have something to diffuse /*if (CELL(world, populations, i, j) > world->diffusionThreshold) { OVERFLOW(world, overflows, i, j) = CELL(world, populations, i, j) * world->diffusionRate; //OVERFLOW(world, overflows, i, j) = 0; }*/ OVERFLOW(world, overflows, i, j) = CELL(world, populations, i, j) * world->diffusionRate; barrier(CLK_GLOBAL_MEM_FENCE); int surplus = OVERFLOW(world, overflows, i + 1, j) + OVERFLOW(world, overflows, i - 1, j) + OVERFLOW(world, overflows, i, j - 1) + OVERFLOW(world, overflows, i, j + 1); //int surplus = 0; CELL(world, newPopulations, i, j) = CELL(world, populations, i, j) + surplus / 8.0 - OVERFLOW(world, overflows, i, j); barrier(CLK_GLOBAL_MEM_FENCE); //CELL(world, newPopulations, i, j) = world->width * 1000 + world->height; //CELL(world, newPopulations, i, j) = surplus; } kernel void death( global CollemWorld *world, global int *populations, global int *patchesType) { /*const int i = get_global_id(0); const int j = get_global_id(1); int patchType = CELL(world, patchesType, i, j); if (patchType == TYPE_ARTIFICIAL) { CELL(world, populations, i, j) = 0; } else if (patchType != world->speciality) { CELL(world, populations, i, j) -= CELL(world, populations, i, j) * world->mortalityRate; }*/ }